没有合适的资源?快使用搜索试试~ 我知道了~
Java并发编程:深入解析抽象队列同步器(AQS)及其在Lock中的应用
需积分: 5 0 下载量 68 浏览量
2023-12-11
21:52:11
上传
评论
收藏 1.06MB PDF 举报
温馨提示
试读
53页
本文深入探讨了Java并发编程的关键组件——抽象队列同步器(AQS)及其在ReentrantLock的应用。AQS是处理线程同步问题的高效工具,是Java并发编程中的核心。文章首先简要介绍了并发编程领域的先驱Doug Lea。 重点在于ReentrantLock的分析,它是基于AQS实现的互斥锁。相比synchronized,它提供了更多特性,如手动加锁解锁,以及公平和非公平锁的选择。公平锁(FairSync)和非公平锁(NonfairSync)的实现是通过AQS的扩展来实现的。 文章进一步阐释了AQS的多项特性,包括阻塞等待队列、共享/独占模式、公平/非公平锁定、可重入性,以及允许中断的能力。AQS作为基础框架,支持了多种同步机制的实现,例如LatchBarrierBlockingQueue等。AQS通过内部类Sync映射所有同步器调用,维护资源状态的可用性 最后,文档提供了AQS源码的初步分析,突出了其设计和实现的关键部分,如等待队列节点类Node的定义 综合来看,文章为Java开发者提供了对AQS及其在ReentrantLock中应用的详细理解,是探索Java并发编程核心概念
资源推荐
资源详情
资源评论
Java并发编程核心在于java.concurrent.util包而juc当中的大多数同步器实现都是围绕
着共同的基础行为,比如等待队列、条件队列、独占获取、共享获取等,而这个行为的抽象
就是基于AbstractQueuedSynchronizer简称AQS,AQS定义了一套多线程访问共享资源
的同步器框架,是一个依赖状态(state)的同步器。
ReentrantLock
ReentrantLock是一种基于AQS框架的应用实现,是JDK中的一种线程并发访问的同步
手段,它的功能类似于synchronized是一种互斥锁,可以保证线程安全。而且它具有比
synchronized更多的特性,比如它支持手动加锁与解锁,支持加锁的公平性。
1 使用ReentrantLock进行同步
2 ReentrantLocklock=newReentrantLock(false);//false为非公平锁,
true为公平锁
3 lock.lock()//加锁
4 lock.unlock()//解锁
ReentrantLock如何实现synchronized不具备的公平与非公平性呢?
在ReentrantLock内部定义了一个Sync的内部类,该类继承AbstractQueuedSynchronized,对
该抽象类的部分方法做了实现;并且还定义了两个子类:
1、FairSync公平锁的实现
2、NonfairSync非公平锁的实现
这两个类都继承自Sync,也就是间接继承了AbstractQueuedSynchronized,所以这一个
ReentrantLock同时具备公平与非公平特性。
上面主要涉及的设计模式:模板模式-子类根据需要做具体业务实现
AQS具备特性
阻塞等待队列
共享/独占
公平/非公平
可重入
允许中断
除了Lock外,Java.concurrent.util当中同步器的实现如Latch,Barrier,BlockingQueue等,
都是基于AQS框架实现
一般通过定义内部类Sync继承AQS
将同步器所有调用都映射到Sync对应的方法
AQS内部维护属性volatileintstate(32位)
state表示资源的可用状态
State三种访问方式
getState()、setState()、compareAndSetState()
AQS定义两种资源共享方式
Exclusive-独占,只有一个线程能执行,如ReentrantLock
Share-共享,多个线程可以同时执行,如Semaphore/CountDownLatch
AQS定义两种队列
同步等待队列
条件等待队列
不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共
享资源state的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/
唤醒出队等),AQS已经在顶层实现好了。自定义同步器实现时主要实现以下几种方法:
isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去
实现它。
tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回
false。
tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回
false。
tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成
功,但没有剩余可用资源;正数表示成功,且有剩余资源。
tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续
等待结点返回true,否则返回false。
同步等待队列
AQS当中的同步等待队列也称CLH队列,CLH队列是Craig、Landin、Hagersten三人
发明的一种基于双向链表数据结构的队列,是FIFO先入先出线程等待队列,Java中的CLH
队列是原CLH队列的一个变种,线程由原自旋机制改为阻塞机制。
条件等待队列
Condition是一个多线程间协调通信的工具类,使得某个,或者某些线程一起等待某个
条件(Condition),只有当该条件具备时,这些等待线程才会被唤醒,从而重新争夺锁
AQS源码分析
1 publicabstractclassAbstractQueuedSynchronizer
2 extendsAbstractOwnableSynchronizer
3 implementsjava.io.Serializable{
4 privatestaticfinallongserialVersionUID=737398497257241469
1L;
5
6 /**
7 *Createsanew{@codeAbstractQueuedSynchronizer}instance
8 *withinitialsynchronizationstateofzero.
9 */
10 protectedAbstractQueuedSynchronizer(){}
11
12 /**
13 *Waitqueuenodeclass.
14 *
15 *不管是条件队列,还是CLH等待队列
16 *都是基于Node类
17 *
18 *AQS当中的同步等待队列也称CLH队列,CLH队列是Craig、Landin、Hagers
ten三人
19 *发明的一种基于双向链表数据结构的队列,是FIFO先入先出线程等待队列,
Java中的
20 *CLH队列是原CLH队列的一个变种,线程由原自旋机制改为阻塞机制。
21 */
22 staticfinalclassNode{
23 /**
24 *标记节点未共享模式
25 **/
26 staticfinalNodeSHARED=newNode();
27 /**
28 *标记节点为独占模式
29 */
30 staticfinalNodeEXCLUSIVE=null;
31
32 /**
33 *在同步队列中等待的线程等待超时或者被中断,需要从同步队列中取消等待
34 **/
35 staticfinalintCANCELLED=1;
36 /**
37 *后继节点的线程处于等待状态,而当前的节点如果释放了同步状态或者被取
消,
38 *将会通知后继节点,使后继节点的线程得以运行。
39 */
40 staticfinalintSIGNAL=‐1;
41 /**
42 *节点在等待队列中,节点的线程等待在Condition上,当其他线程对Condit
ion调用了signal()方法后,
43 *该节点会从等待队列中转移到同步队列中,加入到同步状态的获取中
44 */
45 staticfinalintCONDITION=‐2;
46 /**
47 *表示下一次共享式同步状态获取将会被无条件地传播下去
48 */
49 staticfinalintPROPAGATE=‐3;
50
51 /**
52 *标记当前节点的信号量状态(1,0,‐1,‐2,‐3)5种状态
53 *使用CAS更改状态,volatile保证线程可见性,高并发场景下,
54 *即被一个线程修改后,状态会立马让其他线程可见。
55 */
56 volatileintwaitStatus;
57
58 /**
剩余52页未读,继续阅读
资源评论
光芒软件工匠
- 粉丝: 790
- 资源: 64
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功