condition实现原理
|
void await() throws InterruptedException
|
进入等待,直到被通知或中断
|
|
void awaitUninterruptibly()
|
进入等待,直到被通知,不响应中断
|
|
long awaitNanos(long nanosTimeout) throws InterruptedException
|
等待xxx纳秒
|
|
boolean awaitUntil(Date deadline) throws InterruptedException
|
等待,直到某个时间点
|
|
void signal()
|
唤醒
|
|
void signalAll()
|
唤醒所有等待在condition上的线程,会从等待队列挨个signal()
|
public class BoundedQueue<T> {
private Object[] items;
//添加的下标,删除的下标和数组当前数量
private int addIndex, removeIndex, count;
private Lock lock = new ReentrantLock();
private Condition empty = lock.newCondition();
private Condition full = lock.newCondition();
//构造方法
public BoundedQueue(int size){
items = new Object[size];
}
//添加元素,如果数组满,则添加线程进入等待,直到有空位
public void add(T t) throws InterruptedException{
lock.lock();
try {
while (count == items.length) //改成if会如何
full.await();
items[addIndex] = t;
if(++addIndex == items.length)
addIndex = 0;
++count;
empty.signal();
}finally {
lock.unlock();
}
}
//从头部删除一个元素,如果数组空,则删除线程进入等待状态,直到添加新元素
public T remove() throws InterruptedException{
lock.lock();
try{
while (count == 0)
empty.await();
Object x = items[removeIndex];
if(++removeIndex == items.length)
removeIndex = 0;
--count;
full.signal();
return (T)x;
}finally {
lock.unlock();
}
}
}


public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter(); //当前线程加入等待队列
int savedState = fullyRelease(node); //释放同步状态,也就是释放锁
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // clean up if cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}

public final void signal() {
if (!isHeldExclusively()) //是否获取了锁(重入锁中是直接 return 独占锁线程==当前线程)
throw new IllegalMonitorStateException();
Node first = firstWaiter; //等待队列头节点
if (first != null)
doSignal(first);
}
private void doSignal(Node first) {
do {
if ( (firstWaiter = first.nextWaiter) == null) //等待队列首节点的后继节点为空,说明只有一个节点,那么尾节点也置空
lastWaiter = null;
first.nextWaiter = null;
} while (!transferForSignal(first) && (first = firstWaiter) != null); // 等待队列首节点唤醒失败,则唤醒下个节点
}
final boolean transferForSignal(Node node) {// 将节点加入同步队列
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) // 设置节点状态为0----(等待队列状态只能为-2,-3,用-2进行cas设置失败,说明是-3)
return false;
Node p = enq(node); // 放入同步队列尾部
int ws = p.waitStatus;
if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
LockSupport.unpark(node.thread);
return true;
}

condition实现原理的更多相关文章
- AbstractQueuedSynchronizer 原理分析 - Condition 实现原理
1. 简介 Condition是一个接口,AbstractQueuedSynchronizer 中的ConditionObject内部类实现了这个接口.Condition声明了一组等待/通知的方法,这 ...
- MySQL Index Condition Pushdown 原理与解析
Index Condition Pushdown(ICP)是针对mysql使用索引从表中检索行数据时的一种优化方法. 原理: 在没有ICP特性之前,存储引擎根据索引去基表查找并将数据返回给mysq ...
- lesson5:Condition的原理分析及demo展示
Condition 将 Object 监视器方法(wait,notify,和notifyAll)分解成截然不同的对象,以便通过将这些对象与任意Lock实现组合使用,为每个对象提供多个等待 set(wa ...
- 这一次搞懂SpringBoot核心原理(自动配置、事件驱动、Condition)
@ 目录 前言 正文 启动原理 事件驱动 自动配置原理 Condition注解原理 总结 前言 SpringBoot是Spring的包装,通过自动配置使得SpringBoot可以做到开箱即用,上手成本 ...
- [置顶] SPL讲解(6)--Condition篇
SmartPersistenceLayer 2.0 之 Condition篇 原理 强大的Condition功能是SPL的一个特性,可以使用Condition完成绝大部分的条件定义,使用 ...
- Java并发之Condition
在使用Lock之前,我们使用的最多的同步方式应该是synchronized关键字来实现同步方式了.配合Object的wait().notify()系列方法可以实现等待/通知模式.Condition接口 ...
- 深入理解Java并发之synchronized实现原理
深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...
- JAVA CAS原理深度分析 volatile,偏向锁,轻量级锁
JAVA CAS原理深度分析 http://blog.csdn.net/hsuxu/article/details/9467651 偏向锁,轻量级锁 https://blog.csdn.net/zqz ...
- Condition接口
<Java并发编程艺术>读书笔记 Condition介绍 任意一个Java对象,都拥有一组监视器方法(定义在java.lang.Object中),主要包括wait().wait(long ...
随机推荐
- 【小梅哥FPGA进阶教程】MC8051软核在FPGA上的使用
十.MC8051软核在FPGA上的使用 本教程内容力求以详细的步骤和讲解让读者以最快的方式学会 MC8051 IP core 的应用以及相关设计软件的使用,并激起读者对 SOPC 技术的兴趣.本实验重 ...
- Linux route命令 显示getnameinfo failed [UNKNOWN]
Redhat配置IPv6以后,执行route显示getnameinfo failed [UNKNOWN] 修改/etc/hosts,增加主机名后,重启服务器,问题解决
- @cms_content_list
[@cms_content_list typeId='1,2,3' count='18' orderBy='4' channelId='75' channelOption='0' dateFormat ...
- 5、Semantic-UI之基础按钮样式
5.1 基础按钮样式 在Semantic-UI中定义了很多的按钮样式,可以通过class="ui button"来指定,也可以在class中指定颜色. 示例:定义基础按钮样式 ...
- VCS简介
VCS -Version Control System 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统. 特征 1.记录文件的所有历史变化 2.随时可恢复到任何一个历史状 ...
- linux命令の ./configure --prefix
源码的安装一般由3个步骤组成:配置(configure).编译(make).安装(make install). Configure是一个可执行脚本,它有很多选项,在待安装的源码路径下使用命令./con ...
- ibatis 参数之 String
<select id="query_cust_name" resultClass="_custForm" parameterClass="Str ...
- C#反射(转载)
转载原文出处忘了,一直保存在本地(勿怪) 前期准备 在VS2012中新建一个控制台应用程序(我的命名是ReflectionStudy),这个项目是基于.net 4.0.接着我们打开Program.cs ...
- 《Beginning Java 7》 - 7 - abstract class 抽象类 和 interface 接口
1. 抽象类: 为什么用抽象类: 一些 generic 的类本身并没有现实意义,所以不需要被实例化.比如动物,自然界没有动物这个物种,但却有无数的继承自动物的物种,那么动物本身可以是一个抽象类. 抽象 ...
- “全栈2019”Java第十一章:标识符
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...