java学习-reentrantlock-fair和unfair
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java学习-reentrantlock-fair和unfair,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3014字,纯文字阅读大概需要5分钟。
内容图文
关于reentrantLock 中 fair 和 unfair体现
对于 reentrantLock 其核心实际是利用AbstractQueueSynchronizer (AQS);
对于reentrant就是通过判断当前线程是否相等作为可重入条件
AQS 实际就是一个双向链表组成的队列,对于队列中存在的节点实际就是等待获取锁的线程;
对于AQS一般是设置在有效时间内获取到锁,当获取锁失败的情况下才会被添加到队列中,对于队列中的等待者实际就是通过循环一直尝试获取锁,当在尝试获取锁失败的情况下且未达到获取锁等待时间时,会尝试将当前线程(这里主要是针对的当前执行循环的线程)挂起,当在释放锁的情况下,会通知当前被挂起的线程,重新执行获取锁的过程; 直到获取锁成功或等待获取锁超时或竞争锁的线程消亡,节点才会被移除掉;
对于AQS实际队列的形式满足先进先出(FIFO)的特点;
对于reentrantLock 中的 fair 和 unfair 其主要体现在 当同时存在 未保存到队列中的竞争者 和 队列中排队等候的竞争者 在上一个线程释放锁之后,其获取锁的顺序优先级
- 关于unfair,其核心就是在 当同时存在 未保存到队列中的竞争者 和 队列中排队等候的竞争者时,其并没有优先级的关系,属于公平竞争加锁过程,当使用cas加锁成功后,如果是不属于AQS中的加锁成功,则AQS中的节点会继续等待;如果是AQS中的head 加锁成功,则AQS中的head移除队列;而对于不存在与队列中的竞争者会被追加到链表的尾部作为新的tail节点
- 关于fair,其核心就是 在执行加锁操作时,首先判断队列中是否存在等待的节点,如果存在等待的节点则会终止尝试加锁过程,而是直接追加到队列中;反之,则直接尝试加锁;
public final boolean hasQueuedPredecessors() { // The correctness of this depends on head being initialized // before tail and on head.next being accurate if the current // thread is first in queue. Node t = tail; // Read fields in reverse initialization order Node h = head; Node s; return h != t && // 首先判断队列中是否存在数据,当 h!=t时说明队列中存在数据 // 当队列中存在数据时,判断当前head节点是否已出队,当s==null说明已出队 // 当s!=null时,需要判断s节点的线程是否是当前线程, //当其等于当前线程时,说明队列中下一个等待者就是当前线程 ((s = h.next) == null || s.thread != Thread.currentThread()); }
protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (!hasQueuedPredecessors() && // 首先判断队列中是否存在数据,以及存在的数据下一个等待者是否就是本身 compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
对于fair 中 hasQueuedPredecessors中出现的判断情况
- h !=t ,当结果为false时后续的判断都不需要执行,对于为false说明 h==t,代表队列为空,整体结果返回false;反之为true则表示队列中存在数据;
- (s=h.next) == null,当结果为true时表示当前head节点可能已出队,则后续的流程无需执行,整体结果返回true;当判断s节点不为空时,则继续执行后续的判断
- s.thread != Thread.currentThread(),判断当前head节点的后续节点是否为当前线程,如果为false说明是当前线程,则整体返回结果为false;如果为true,说明不是当前线程,则整体结果返回true;
因此对于fair 情况下,能直接进行尝试加锁的情况就只有以下两种情况
- 队列为空
- 当前请求存在于队列中,且就是下一个等待者节点
简单总结一下,对于fair主要是针对AQS队列中元素的公平
内容总结
以上是互联网集市为您收集整理的java学习-reentrantlock-fair和unfair全部内容,希望文章能够帮你解决java学习-reentrantlock-fair和unfair所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。