Java并发的类库_Java 并发类库AbstractQueuedSynchronizer 分析

java.util.concurrent.locks.AbstractQueuedSynchronizer.compareAndSetState(int, int)

子类推荐被定义为自定义同步装置的内部类,同步器自身没有实现任何同步接口,它仅仅是定义了若干acquire之类的方法来供使用。该同步器即可以作为排他模式也可以作为共享模式,当它被定义为一个排他模式时,其他线程对其的获取就被阻止,而共享模式对于多个线程获取都可以成功。

同步器是实现锁的关键,利用同步器将锁的语义实现,然后在锁的实现中聚合同步器。可以这样理解:锁的API是面向使用者的,它定义了与锁交互的公共行为,而每个锁需要完成特定的操作也是透过这些行为来完成的(比如:可以允许两个线程进行加锁,排除两个以上的线程),但是实现是依托给同步器来完成;同步器面向的是线程访问和资源控制,它定义了线程对资源是否能够获取以及线程的排队等操作。锁和同步器很好的隔离了二者所需要关注的领域,严格意义上讲,同步器可以适用于除了锁以外的其他同步设施上(包括锁)。

2. CLH算法

锁的实现是以CLH算法为基础。下面简单介绍一下CLH算法: CLH算法构建了隐式的链表,是一种非阻塞算法的实现。CLH队列中的结点QNode中含有一个locked字段,该字段若为true表示该线程需要获取锁,且不释放锁,为false表示线程释放了锁。结点之间是通过隐形的链表相连,之所以叫隐形的链表是因为这些结点之间没有明显的next指针,而是通过myPred所指向的结点的变化情况来影响myNode的行为。CLHLock上还有一个尾指针,始终指向队列的最后一个结点。CLHLock的类图如下所示:

09b5c83ae6fd1a1b276688d4e664b03a.pngvcewx/e94bXjys23xcv4oaO1sdK7uPbP37PM0OjSqsrNt8XL+Mqxo6y9q7Wxx7C94bXjtcRsb2NrZWTT8sno1sPOqmZhbHNlo6zNrMqxu9jK1cewx/e94bXjoaPI58/CzbzL+cq+o6zP37PMQdDo0qq78cihy/ijrMbkbXlOb2Rl0/LOqnRydWWjrNCpyrF0YWls1rjP8s/fs8xBtcS94bXjo6zIu7rzz9+zzELSsrzTyOu1vc/fs8xBuvPD5qOsdGFpbNa4z/LP37PMQrXEveG146GjyLu688/fs8xBus1CtrzU2sv8tcRteVByZWTT8snP0P3XqqOs0rvBv8v8tcRteVByZWS94bXjtcRsb2NrZWTX1rbOseTOqmZhbHNlo6zL/L7Nv8nS1LvxyKHL+Mmo0NCho8P3z9TP37PMQbXEbXlQcmVkCiBsb2NrZWTT8s6qZmFsc2WjrLTLyrHP37PMQbvxyKG1vcHLy/ihowo8aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20140213/2014021309011484.jpg" width="500" height="400" alt="\">

整个CLH的代码如下,其中用到了ThreadLocal类,将QNode绑定到每一个线程上,同时用到了AtomicReference,对尾指针的修改正是调用它的getAndSet()操作来实现的,它能够保证以原子方式更新对象引用。 CLH算法的示意代码如下:

74ac1f517421d8c61ef40c717953278a.png

3.AQS实现分析

3.1 概述

同步器的设计包含获取和释放两个操作:

获取操作过程如下:

3、内部应该维护一个队列。

AQS的实现采用了模板设计模式,在AbstractQueuedSynchronizer类中,定义了

3.2 获取、释放锁操作

3.2.1 获取操作

获取锁操作的代码如下:

addWaiter方法如下:

acquireQueued代码如下:

需要注意的是,acquire在执行过程中,并不能及时的对外界中断进行相应,必须等待执行完毕之后,如果由外部中断,则进行中断响应。与acquire方法类似,acquireInterruptibly方法提供了获取状态能力,当然在无法获取状态的情况下会进入sync队列进行排队,这类似acquire,但是和acquire不同的地方在于它能够在外界对当前线程进行中断的时候提前结束获取状态的操作,换句话说,就是在类似synchronized获取锁时,外界能够对当前线程进行中断,并且获取锁的这个操作能够响应中断并提前返回。一个线程处于synchronized块中或者进行同步I/O操作时,对该线程进行中断操作,这时该线程的中断标识位被设置为true,但是线程依旧继续运行。

3.2.2 释放操作

释放操作代码如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值