5.4 读写锁
之前提到的锁如Mutex和ReentrantLock都是排它锁,这些锁同一时刻都只允许一个线程进行访问。而读写锁在同一时刻可以允许多个读线程进行访问,但在写线程访问时,所有的其他读线程和写线程均被阻塞。
读写锁维护了一个同步器,一个读锁和一个写锁。读锁lock()时调用同步器的tryAcquireShared方法,写锁lock()时调用同步器tryAcquire方法。
5.6 Condition接口
任意一个Java对象,都拥有一组监视器方法(定义在java.lang.Object上),主要包括wait(),wait(long timeout),notify()以及notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式。
Condition接口定义了等待/通知两种类型的方法,当前线程调用这些方法时,需要提前获取到Condition对象关联的锁。Condition对象是由Lock对象(调用Lock对象的newCondition()方法)创建出来的,换句话来说,Condition是依赖Lock对象的。
Object的监视器方法与Condition接口的对比:
(1)Condition支持在等待状态中不响应中断(void awaitUninterruptibly)。
(2)Condition支持当前线程释放锁并进入等待状态直至将来某个时间(boolean awaitUntil(Date deadline) throws InterruptedException)。
Condition的部分方法以及描述:
(1)void await() throws InterruptedException:当前线程进入等待状态直至被通知(signal)或被中断。如果当前线程从await()方法中返回,那么表明该线程已经或得了Condition对象所对应的锁。
(2)void awaitUninterruptibly():当前线程进入等待状态,不响应中断。
(3)long awaitNanos(long nanosTimeout)throws InterruptedException:当前线程进入等待状态直到被通知,中断或者超时。返回值表示剩余时间(nanosTimeout-实际耗时),如果返回值是0或者负数,那么可以认定超时了。
(4)boolean awaitUntil(Date deadline) throws InterruptedException:当前线程进入等待状态直到被通知,中断或者到达某个时间点。如果没有到达某个时间点就被通知,方法返回true,否则表示到达了指定时间,方法返回false。
(5)void signal():唤醒一个等待在Condition上的线程,该线程从等待方法返回前必须获得与Condition相关联的锁。
(6)void signalAll():唤醒所有等待在Condition上的线程,能够从等待方法返回的线程必须获得与Condition相关联的锁。