天天看点

《java多线程编程核心技术》笔记

一.java多线程基础:熟悉Thread类

1.2实现多线程方法:

继承Thread类

实现Runnable接口

1.4isAlive()

1.5sleep()

1.6getId()

1.7停止线程:

interrupt():把标志位设置而已,不会立即停止
 interrupted():当前线程是否中断?状态标志位置为false
 isInterrupted():线程是否中断
 抛出异常(建议)
 调用处interrupt(),线程run中判断标志位,return停止线程
           

1.8暂停线程:

suspend()

resume()

1.9让出cpu

yield()

二.对象及变量的并发访问

2.1.synchronized同步方法:

方法变量线程安全。

多个线程访问一个对象的实例变量不安全。

synchronized方法为对象锁,需要该对象锁的都必须同步(包括synchronized(this)),不需要锁的随时读取,所以特别要注意脏读。

为可重入锁,可自己再次获取自己内部锁,有点像总统到期自己继续做总统。

异常自动释放锁

同步不可继承

2.2synchronized代码块:

synchronized(this)

synchronized(非this对象):一般不用String,而new Object()或者object作形参,锁object.

2.3volatile

使所读数据从内存直接读取,而非线程的缓存

不具备原子性:一百个线程对volatile cnt加一,然后输出。结果不具原子性,仍需加锁。

AtomicInteger i++线程安全。但方法调用不具有原子性,原子类操作数据也不一定安全。

三.线程间通讯

3.1:等待/通知

wait() notify():notify()唤醒线程到就绪态,还需拿到锁才能执行。

wait()释放锁,notify()不释放锁。

执行wait()的线程如果interupt()会抛异常

notify()随机唤醒一个线程,要唤醒全部可用notifyAll(),

wait(long)

单生产消费模型–》多生产多消费

3.2:join()

threadTest.join():等等我

threadTest.join(long):等我一会

join()+interupt():可能冒异常

join()释放锁,sleep()不释放锁

3.3ThreadLocal:

希望每个线程有自己的值,每个线程有私有数据,具有隔离性。set进去,get()出来

第一次get()为null,为解决,可以自定义类继承ThreadLocal,自定义初始值

四.Lock

ReentrantLock为lock的实现类,同步锁,比synchronized拥有更强大功能

4.1new ReentrantLock()出来,然后.lock()即上锁,需要手动释放锁.unlock()。中间部分为同步。同步代码间都需要抢同一把锁

4.2Condition对象用于实现等待/通知,.await()必须先上锁.

await()等同于wait()

await(long time,TimeUnit unit)等同于wait(long timeout)

signal()等同于notify()

signalAll()等同于notifyAll()

4.3通知部分线程使用多个Condition

4.4回忆生产消费者模型:生产方法如何,消费方法如何

4.5可以new ReentrantLock(boolean flag)生成公平/非公平锁

4.6ReentrantLock几个方法

getHoldCount():用lock()的次数
getQueueLength():等待获取锁的线程估计数
getWaitQueueLength(Condition condition):返回等待与此锁定相关的Condition的线程估计数
hasQueueThread(Thread thread):查询指定线程是否正等待获取锁
hasWaiters(Condition condition):是否有线程正等待condition
isFair():是否公平
isHeldByCurrentThread():当前线程是否保持锁
isLocked():查询锁是否由任意线程拿了
tryLock():锁没被别的线程拿我才拿
tryLock(long timeout,TimeUnit unit)
           

4.7ReentrantReadWriteLock

读读锁不互斥

含写操作都互斥

五.定时器Timer

5.1new Timer(true),自定义myTask extends TimerTask重写run方法,设置时间,把myTask丢进去。

schedule(TimeTask task,Date time)

一个Timer可以运行多个TimerTask,但是队列形式执行,后任务时间可能延迟。

5.2指定间隔周期性无限循环执行某一任务

timer.schedule(TimerTask task, Date firstTime, long period);

TimerTask的cancel()是将自身从任务队列清除。

Timer的cancel()是将任务队列清空。

5.3在此时间基础上延迟指定毫秒执行一次TimerTask.

schedule(TimerTask task,Long delay)

5.4延迟指定毫秒,某间隔无限次数执行某一任务

schedule(TimerTask task,long delay,long period)