关于AbstractQueuedSynchronizer
JDK1.5之后引入了并发包java.util.concurrent,大大提高了Java措施的并发机能。关于java.util.concurrent包我总结如下:
可以说AbstractQueuedSynchronizer是并发类的重中之重。其实之前在ReentrantLock实现道理深入探究一文中已经有团结ReentrantLock具体解读过AbstractQueuedSynchronizer,但限于其时程度原因,回看一年半前的此文,感受对付AbstractQueuedSynchronizer的解读领略还不足深,因此这里更新一篇文章,再次解读AbstractQueuedSynchronizer的数据布局即相关源码实现,本文基于JDK1.7版本。
AbstactQueuedSynchronizer的根基数据布局
AbstractQueuedSynchronizer的根基数据布局为Node,关于Node,JDK作者写了具体的注释,这里我大抵总结几点:
下面我用一张表格总结一下Node中持有哪些变量且每个变量的寄义:
关于SIGNAL、CANCELLED、CONDITION、PROPAGATE四个状态,JDK源码的注释中同样有了具体的解读,再用一张表格总结一下:
AbstractQueuedSynchronizer供子类实现的要领
AbstractQueuedSynchzonizer是基于模板模式的实现,不外它的模板模式写法有点出格,整个类中没有任何一个abstract的抽象要领,取而代之的是,需要子类去实现的那些要领通过一个要领体抛出UnsupportedOperationException异常来让子类知道。
AbstractQueuedSynchronizer类中一共有五处要领供子类实现,用表格总结一下:
这里的acquire欠好翻译,所以就直接原词放上来了,劳务派遣管理系统,因为acquire是一个动词,后头并没有带宾语,因此不知道详细acquire的是什么。凭据我小我私家领略,acquire的意思该当是按照状态字段state去获取一个执行当前行动的资格。
好比ReentrantLock的lock()要领最终会挪用acquire要领,那么:
这种领略我认为该当是较量精确的。
独有模式acquire实现流程
有了上面的这些基本,我们看一下独有式acquire的实现流程,主要是在线程acquire失败后,是如何构建数据布局的,先看理论,之后再用一个例子绘图说明。
看一下AbstractQuueuedSynchronizer的acquire要领实现流程,acquire要领是用于独有模式下举办操纵的:
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
tryAcquire要领前面说过了,是子类实现的一个要领,假如tryAcquire返回的是true(乐成),即表白当前线程得到了一个执行当前行动的资格,自然也就不需要构建数据布局举办阻塞期待。
假如tryAcquire要领返回的是false,那么当前线程没有得到执行当前行动的资格,接着执行”acquireQueued(addWaiter(Node.EXCLUSIVE), arg))”这句代码,这句话很明明,它是由两步组成的:
别离看一下每一步做了什么。
addWaiter
先看第一步,addWaiter做了什么,从传入的参数Node.EXCLUSIVE我们知道这是独有模式的:
private Node addWaiter(Node mode) { Node node = new Node(Thread.currentThread(), mode); // Try the fast path of enq; backup to full enq on failure Node prev = tail; if (prev != null) { node.prev = prev; if (compareAndSetTail(prev, node)) { prev.next = node; return node; } } enq(node); return node; }