上一篇文章介绍了AQS的基本原理,它其实就是一个并发包的基础组件,用来实现各种锁,各种同步组件的。它包含了state变量、加锁线程、等待队列等并发中的核心组件,现在我们来看一下多线程获取锁的顺序问题。

 1   /**
2 * Creates an instance of {@code ReentrantLock}.
3 * This is equivalent to using {@code ReentrantLock(false)}.
4 */
5 public ReentrantLock() {
6 sync = new NonfairSync();
7 }
8
9 /**
10 * Creates an instance of {@code ReentrantLock} with the
11 * given fairness policy.
12 *
13 * @param fair {@code true} if this lock should use a fair ordering policy
14 */
15 public ReentrantLock(boolean fair) {
16 sync = fair ? new FairSync() : new NonfairSync();
17 }
ReentrantLock有两个构造参数,一个有参,一个无参,默认的无参相当于有参数的false。
 1      /**
2 * Performs non-fair tryLock. tryAcquire is implemented in
3 * subclasses, but both need nonfair try for trylock method.
4 */
5 final boolean nonfairTryAcquire(int acquires) {
6 final Thread current = Thread.currentThread();
7 int c = getState();
8 if (c == 0) {
9 if (compareAndSetState(0, acquires)) {
10 setExclusiveOwnerThread(current);
11 return true;
12 }
13 }
14 else if (current == getExclusiveOwnerThread()) {
15 int nextc = c + acquires;
16 if (nextc < 0) // overflow
17 throw new Error("Maximum lock count exceeded");
18 setState(nextc);
19 return true;
20 }
21 return false;
22 }

如果为参数为false为非公平锁,非公平锁获取锁的方式为如果当前没有线程占有锁,当前线程直接通过cas指令占有锁,管他等待队列,就算自己排在队尾也是这样

 1        /**
2 * Fair version of tryAcquire. Don't grant access unless
3 * recursive call or no waiters or is first.
4 */
5 protected final boolean tryAcquire(int acquires) {
6 final Thread current = Thread.currentThread();
7 int c = getState();
8 if (c == 0) {
9 if (!hasQueuedPredecessors() &&
10 compareAndSetState(0, acquires)) {
11 setExclusiveOwnerThread(current);
12 return true;
13 }
14 }
15 else if (current == getExclusiveOwnerThread()) {
16 int nextc = c + acquires;
17 if (nextc < 0)
18 throw new Error("Maximum lock count exceeded");
19 setState(nextc);
20 return true;
21 }
22 return false;
23 }
 1 public final boolean hasQueuedPredecessors() {
2 // The correctness of this depends on head being initialized
3 // before tail and on head.next being accurate if the current
4 // thread is first in queue.
5 Node t = tail; // Read fields in reverse initialization order
6 Node h = head;
7 Node s;
8 return h != t &&
9 ((s = h.next) == null || s.thread != Thread.currentThread());
10 }

如果为参数为true为公平锁,公平锁获取锁的方式为如果当前线程是等待队列的第一个或者等待队列为空或为当前占有线程,则通过cas指令设置state为1或增加。公平锁加锁的线程全部是按照先来后到的顺序,依次进入等待队列中排队的,不会盲目的胡乱抢占加锁。

 

最新文章

  1. [SAP ABAP开发技术总结]选择屏幕——各种屏幕元素演示
  2. DDX_Text ()函数 C++
  3. FadeTop – 定时休息提醒工具
  4. 在WINDOWS上安装oracle database 11
  5. mysql max_allowed_packet错误
  6. U口破解指令介绍.
  7. password学3——Java BASE64加密解密
  8. 大话spring.net之IOC
  9. Sublime Text 3 修改配色主题【侧边框之...】
  10. redux源码解读
  11. javascript进制转换
  12. 实验六:通过grub程序引导本地磁盘内核启动系统(busybox)
  13. es安装ik后报错无法启动 read write
  14. ABAP的匹配
  15. Oracle 学习笔记(六)
  16. LeetCode--349--两个数组的交集
  17. gcc请不要优化
  18. LeetCode - 463. Island Perimeter - O(MN)- (C++) - 解题报告
  19. 嵌入式框架Zorb Framework搭建二:环形缓冲区的实现
  20. [独孤九剑]Oracle知识点梳理(四)SQL语句之DML和DDL

热门文章

  1. [PyTorch 学习笔记] 1.4 计算图与动态图机制
  2. 简单的股票信息查询系统 1 程序启动后,给用户提供查询接口,允许用户重复查股票行情信息(用到循环) 2 允许用户通过模糊查询股票名,比如输入“啤酒”, 就把所有股票名称中包含“啤酒”的信息打印出来 3 允许按股票价格、涨跌幅、换手率这几列来筛选信息, 比如输入“价格&gt;50”则把价格大于50的股票都打印,输入“市盈率&lt;50“,则把市盈率小于50的股票都打印,不用判断等于。
  3. Linux环境安装Docker入门教程
  4. 洛谷T90444 密码 题解
  5. classmethod与staticmethod
  6. idea 执行maven打包命令时,修改war包名称
  7. 前端ES6 一些面试题
  8. 从String中移除空白字符的多种方式!?
  9. C++类重载函数的function和bind使用
  10. 02 axios