第13章 显式锁
在Java 5.0中增加了一种新的机制 :ReentrantLock。
13.1 Lock 与 ReentrantLock
Lock提供了一种无条件、可轮询、定时的以及可中断的锁获取操作。
public interface Lock{
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
防止死锁的唯一方法是避免出现不一致的锁顺序,可定时的与可轮询的锁提供了另外一种选择:避免死锁的发生。—-》tryLock
内置锁的阻塞机制让实现可取消的任务变得复杂, lockInterruptibly可以保持对中断的响应。
ReentrantLock 提供了两种公平性的选择,默认非公平的锁,或者一个公平的锁。非公平的锁允许插队,如果在发出请求到该锁的状态变成可用,则这个线程可以跳过队列中的所有等待线程直接获得锁。
13.2 ReadWriteLock
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock r = lock.readLock();
private final Lock w= lock.writeLock();
第14章 构建自定义的同步工具
类库包含了许多存在状态依赖性的类,如FutureTask, Semaphore, BlockingQueue等。如果基于某个状态的前置条件未得到满足,这个条件就永远无法为真。在再次测试前提条件的时候,必须重新获得锁。
acquire lock on object state
while(precondition does not hold){
release lock
wait until precondiion might hold
optionally fail if interrupted or timeout expires
reacquire lock
}
preform action
release lock
14.1 条件队列
一组线程(称之为等待线程集合)能够通过某种方式来等待特定的条件变成真。
Object.wait, notify和notifyAll 构成了内部条件队列的API。
Object.wait 会自动释放锁,并请求操作系统挂起当前线程,从而其他线程能够获得这个锁并修改对象的状态。当一个线程由于调用notifyAll而醒来时,并不意味该线程正在等待的条件谓词已经成真。
notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。notify则文明得多他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁此时如果该对象没有再次使用notify语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。
14.2 显示的Condition对象
一个Condition和一个Lock是关联在一起的,就像一个条件队列和一个内置锁一样。对于每个Lock,可以有任意数量的Condition对象。
-**在Condition对象中,与wait,notify,notifyAll方法分别对应的是await, signal, signalAll.
14.3 AbstractQueuedSynchronizer
第15章 原子变量与非阻塞同步机制
15.1 CAS
第16章 Java内存模型