Condition中的transferForSignal()方法的不解
Node p = enq(node);
···
if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))LockSupport.unpark(node.thread);// 唤醒节点上的线程return true;
···
通过enq放入同步队列了,他自己会慢慢的争抢锁,就像synchronize中的wait,为什么这里要进行一次unpark?
先看下判断条件。
ws>0,说明是1,是CANCELLED状态,!compareAndSetWaitStatus(p, ws, Node.SIGNAL)) 什么时候把前一个节点(enq(node);返回当前节点的前一个节点,也就是原来的tail)赋值为SIGNAL状态失败?就是前一个节点是CANCELLED的时候,好吧这两个好像是一个命题。
接着看为什么这里要进行一次unpakr?
10-12行的迷惑性就来源于此。实际上,就算去掉10-12行也是满足正确性要求的。因为线程T2释放锁后,依然会将从队头开始的第一个非取消节点唤醒,该节点会继续ConditionObject#await()中的工作(稍后回去分析)。10-12行是为了进一步提升性能,针对两种情况:
- 如果插入node前,AQS内部等待队列的队尾节点就已经被取消,则满足wc > 0
- 如果插入node后,AQS内部等待队列的队尾节点已经稳定,满足tail.waitStatus == 0,但在执行ws >
0之后!compareAndSetWaitStatus(p, ws,
Node.SIGNAL)之前被取消,则CAS也会失败,满足compareAndSetWaitStatus(p, ws,
Node.SIGNAL) == false
这两种情况下,提前唤醒node能够在等待锁的同时,预先完成一部分ConditionObject#await()中无需同步的工作。这部分成本不能被轻易忽视,因为条件队列被应用最多的场景是高并发,大量线程累加起来的成本是很可观的。
链接:https://www.jianshu.com/p/a932c184db52
在从condition队列到同步队列之前,tail节点被取消了
在从condition队列到同步队列之后,tail节点没被取消,执行完ws > 0
之后,这段时间,被取消了?就通过!compareAndSetWaitStatus(p, ws, Node.SIGNAL)再判断一下这个时候偷偷的提前执行一波,就算不提前执行,AQS队列会不断的把取消节点取消掉,最终还是被unpark的。
总的意思就是为了提升性能,没有这里也是合理的。
Condition中的transferForSignal()方法的不解相关推荐
- python中文读音ndarray-numpy中的ndarray方法和属性详解
NumPy数组的维数称为秩(rank),一维数组的秩为1,二维数组的秩为2,以此类推.在NumPy中,每一个线性的数组称为是一个轴(axes),秩其实是描述轴的数量.比如说,二维数组相当于是一个一维数 ...
- junit4 assert类中的assert方法总结
junit中的assert方法全部放在Assert类中,总结一下junit类中assert方法的分类. 1.assertTrue/False([String message,]boolean cond ...
- 如何去掉DataTable中的重复行(新增.net 2.0中最新解决方法---简便)
.net 1.1中的解决方法(转) 1建立一个DataSetHelper类(DataSetHelper.cs) public class DataSetHelper ...{ public D ...
- 数组中的filter方法_数组filter()方法以及JavaScript中的示例
数组中的filter方法 JavaScript filter()方法 (JavaScript filter() method) filter() method is used to returns a ...
- 关于java中线程yield()方法问题
关于java中线程yield()方法问题 问题一: 我知道yield是用来休眠当前线程,但我查看了资料,又说其不会释放锁,所以我就不解了,其明明会将cpu资源给其他线程,那它不释放锁,其他线程有怎么获 ...
- 自定义附加属性在XAML中的表示方法以及绑定的注意事项
在XMAL中的表示方法 必须把在XAML中导入CLR名称空间 <UserControlxmlns="http://schemas.microsoft.com/winfx/2006/xa ...
- 关于学习java函数式接口Function中的apply方法的一些感悟
起因是这样的,学习函数式编程的时候学到了Function接口,对于其中的apply方法感到不解,下面贴上我的不解代码 在这里插public class Function接口 {public stati ...
- MIT18.065 数据分析、信号处理和机器学习中的矩阵方法-学习笔记
文章目录 MIT18.065 数据分析.信号处理和机器学习中的矩阵方法 Lecture 1 The Column Space of A Contains All Vectors Ax A=CR A=C ...
- java中list中sublist_Java 中 List.subList() 方法的使用陷阱
前言 本文原先发表在我的 iteye博客: http://clevergump.iteye.com/admin/blogs/2211979, 但由于在 iteye发表的这篇文章的某些渲染曾经出现过一些 ...
最新文章
- java怎么表示log2_Java程序员修炼之道 之 Logging(2/3) - 怎么写Log
- iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)
- 打造一个宇宙 星系模拟产生对宇宙进化惊人见解
- VTK:Utilities之AnimationScene
- 开源 | App 开发神仙工具:帮你抓 Bug
- Linux ping不通百度的解决方法
- 浸会大学计算机专业硕士排名2019,2019软科世界大学学术排名香港浸会大学排名第701-800...
- java银行叫号模拟系统_Java 模拟银行叫号机
- 全屏使用swiper.js过程中遇到的坑
- 【Python】Python3.7.3 - memoization 结果缓存记忆程序设计优化技术
- Android 之神 Jake Wharton 从 Square 离职!
- 计算机中内存存储器最小单位,计算机中存储容量的最小单位和最基本单位是什么?...
- psd导出jpg太大_【设计】PSD导出JPG文件非常大解决办法
- python ttk style,如何改变ttk.progressBar颜色在python
- 名字里有计算机里没有的字体大小,公安13000字的庞大字库打不出这些字 五市民名字让电脑“犯晕”...
- Java main是什么_java中的public static void main是什么意思
- 设计模式(一)设计模式的分类与区别
- python通过接口判断公共节假日
- 封神台靶场-尤里的复仇-第二章
- 中控门禁无法添加设备,提示表结构不存在或接收超时
热门文章
- Linux 将文件打包、压缩并分割成指定大小
- 面试题25: 合并两个排序的链表
- 洛谷 P2596 [ZJOI2006]书架 (splay)
- ACM数论之旅2---快速幂,快速求a^b
- python之路_计算机编码及运算符介绍
- [NOIP2006] 数列
- 1 客户端性能--浏览器页面处理
- Michael-Scott非阻塞队列(lock-free)算法的C实现
- selenium(2.4.0)中不能导出web drive 代码
- 4 系统的 CPU 使用率很高,但为啥却找不到高 CPU的应用?