一个基于AQS的Synchronizer所执行的基本操作,是一些不同形式的获取(acquire)和释放(release).获取操作是状态依赖的操作,总能够阻塞。借助锁和信号量,“获取”的含义变得相当直观--获取锁或者许可--并且调用者可能不得不去等待,直到Synchronizer处于可发生的状态。CountDownLatch的请求意味着“等待,直到闭锁到达它的终止态”,FutureTask则意味着“等待,直到任务已经完成”。“释放”不是一个可阻塞的操作:“释放”可以允许线程在请求执行前阻塞。
为了让一个类具有状态依赖性,它必须拥有一些状态。同步类中有一些状态需要管理,这项任务落在AQS上:它管理一个关于状态信息的单一整数,状态信息可以通过protected类型的getState,setState和compareAndSetState等方法进行操作。这可以用于表现任何状态:例如,ReentrantLock用它来表现拥有它的线程已经请求了多少次锁,Semaphore用它来表现剩余的许可数,FutureTask用它来表示任务的状态(尚未开始,运行,完成和取消)。Synchronizer也可以自己管理一些额外的状态变量;如,ReentrantLock保存了当前锁的所有者的追踪信息,这样它就能区分出是重进入的(reentrant)还是竞争的(contended)条件锁。
AQS中获取和释放操作的规范式:
boolean acquire() throws InteruptedException{
while (state does not permit acquire){
if(blocking acquisition requested){
enqueue current thread if not already queued
block current thread
}
else
return failure
}
possibly update synchronization state
dequeue thread if it was queued
return sucess
}
void release(){
update synchronization state
if (new state may permit a blocked thread to acquire)
unblock on or more queued threads
}
本文介绍了AbstractQueuedSynchronizer(AQS)的工作原理及其在Java并发编程中的应用。AQS为构建锁和其他同步组件提供了框架支持,通过维护一个内部状态和一组等待线程来实现同步。文章详细解释了获取和释放操作的流程,并列举了ReentrantLock、Semaphore和FutureTask等基于AQS实现的示例。
745

被折叠的 条评论
为什么被折叠?



