ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JAVA并发编程学习17(AQS学习)

2021-07-07 19:04:33  阅读:230  来源: 互联网

标签:JAVA 17 AQS 对象 state 线程 当前 如果


AQS是Java并发包中的抽象类AbstractQueuedSynchronizer的简称,其整体的架构架构设计如下图:

ReentrantLock

对于ReentrantLock来说,其执行逻辑如下所示:

1.尝试获取对象的锁,如果获取不到(意味着已经有其它线程持有了锁,并且尚未释放),那么它(当前线程)就会进入到AQS的阻塞队列当中。

2.如果获取到,那么根据锁是公平锁还是非公平锁来进行不同处理:

        2-1.如果是公平锁,那么线程会被直接放置到AQS阻塞队列的末尾

        2-2.如果是非公平锁,那么线程会首先尝试进行CAS计算,如果成功,则直接获取到锁;如果失败,则与公平锁的处理方式一致,当前线程会被放置到阻塞队列末尾。

3.当锁被释放时(调用了unlock方法),那么底层会调用release方法对state成员变量的值进行减一操作,如果减一后,state的值不为0,那么release操作就执行完毕;如果减一操作后,state的值为0,则调用LockSupport的unpark方法唤醒该线程后的等待队列中的第一个后继线程(底层通过pthread_mutex_unlock指令),将其唤醒,使之能够获取到对象的锁(release时,对于公平锁与非公平锁的处理逻辑是一致的);之所以调用release方法后state的值可能不为零,其原因在于ReentrantLock是可重入锁,表示线程可以多次调用lock方法,导致每调用一次,state的值都会加一。

对于ReentrantLock来说,所谓的上锁,本质上就是对AQS中的state成员变量的操作:对该成员变量+1,表示上锁;对该成员变量-1,表示释放锁。

ReentrantReadWriteLock

关于ReentrantReadWriteLock的操作逻辑:

读锁:

1.在获取读锁时,会尝试判断当前对象是否拥有了写锁,如果已经拥有,则直接失败;

2.如果没有写锁,就表示当前对象没有排它锁,则当前线程会尝试给对象加锁;

3.如果当前线程已经持有了该对象的锁,那么直接将读锁的数量加1.

写锁:

1.在获取写锁时,会尝试判断当前对象是否拥有了锁(读锁与写锁),如果已经拥有锁且持有锁的线程并非当前线程,则直接失败。

2.如果当前对象没有被加锁,那么写锁就会为当前对象上锁,并且将写锁的个数加1;

3.将当前对象的排它锁线程持有者设置为自己。

标签:JAVA,17,AQS,对象,state,线程,当前,如果
来源: https://blog.csdn.net/qq_32852017/article/details/118554477

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有