注意:所有文章除特别说明外,转载请注明出处.
[TOC]
第四章 Lock的使用
4.1 使用ReentrantLock类
与synchronize关键字类似,能够实现线程之间同步互斥,同时扩展功能使得其更加强大。
4.1.1 ReentrantLock 实现同步
提示:当前线程在运行完之后将进行锁释放,其它线程才可以继续执行。
提示:调用ReentrantLock对象的lock()方法获取锁,调用unlock()方法释放锁。
调用了 lock.lock() 程序的线程就持有了“对象监视器”,其它线程只有等待锁被释放时再次争抢。效果和使用synchronize关键字一样,线程之间还是顺序执行的。
4.1.3 使用Condition实现等待/通知
由于关键字 synchronized 与wait()和notify()方法/notifyAll()方法相结合可以实现等待/通知模式,类ReentrantLock也可以实现同样的功能,但是需要借助 Condition 对象。
Condition 有更好的灵活性,可以实现多路通知功能,表示在一个Lock对象里面可以创建多个Condition(对象监视器)实例,线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度上更加灵活。
提示:synchronized 相当于整个Lock对象中只有一个单一的Condition对象,所有的线程都注册在它一个对象上。
注意:必须在condition.await()方法调用之前调用 lock.lock()方法获取同步监视器。
4.1.4 正确使用Condition实现等待/通知
1.Object类中的 wait() 方法相当于 Condition类中的await()方法。
2.Object类中的 wait(long timeout) 方法相当于 Condition类中的await(long time, TimeUnit unit)方法。
3.Object类中的 notify()方法相当于 Condition类中的signal()方法。
4.Object类中的 notifyAll()方法相当于 Condition类中的 signalAll()方法。
4.1.5 实现多个Condition通知部分线程
使用 ReentrantLock 对象可以唤醒指定种类的线程,这是控制部分线程行为的有效方式。
4.2 使用 ReentrantReadWriteLock 类
类 ReentrantLock 具有完全互斥排它的效果,即同一时间只有一个线程在执行 ReentrantLock.lock()方法后面的任务。虽然保证实例变量的安全性,但效率低下。
读写锁 ReentrantReadWriteLock 表示两个锁,一个读锁(共享锁),一个写锁(排它锁)。即表示多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥。
提示:多个线程可以同时进行读取操作,但是同一时刻只允许一个线程进行写入操作。
提示:在读读共享中,使用 lock.readLock() 读锁可以提高程序运行效率,允许多个线程同时执行 lock() 方法后面的程序。
提示:在写写互斥中,使用 lock.writeLock() 的效果就是同一时间只允许一个线程执行 lock() 方法后面的代码。
提示:在读写互斥中,使用 lock.writeLock() | lock.readLock() 的效果就是同一时间只允许一个线程执行 lock() 方法后面的代码。