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 ...
随机推荐
- Activity Fragment转场动画
Activity转场动画 先介绍个动画的好例子:https://github.com/lgvalle/Material-Animations Activity的转场动画是通过overridePendi ...
- mysql查询最近7天的数据,没有数据自动补0
问题描述 查询数据库表中最近7天的记录 select count(*),date(create_time) as date from task where datediff(now(),create_ ...
- [LINK]List of .NET Dependency Injection Containers (IOC)
http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx I'm trying to expand my ...
- Partition--分区总结
1. 在SQL SERVER 2008 R2 SP2之前版本,对分区只支持到1000个分区,之后版本支持到15000个分区.2. 分区索引对齐并不要求索引和表使用同一分区方案,但要求两者使用的分区方案 ...
- IOS 6 自动布局 入门
http://blog.csdn.net/itianyi/article/details/8535392
- layui后台框架的搭建
layui(谐音:类UI) 是一款采用自身模块规范编写的前端 UI 框架,遵循原生 HTML/CSS/JS 的书写与组织形式,门槛极低,拿来即用.其外在极简,却又不失饱满的内在,体积轻盈,组件丰盈,从 ...
- Re:从零开始的Spring Security Oauth2(三)
上一篇文章中我们介绍了获取token的流程,这一篇重点分析一下,携带token访问受限资源时,内部的工作流程. @EnableResourceServer与@EnableAuthorizationSe ...
- layer模态窗简单使用
layer.open({ type: 1,//模态窗种类 skin: "layui-layer-rim", title: "编辑信息", area: [&quo ...
- 反射:获取Class对象的三种方式
获取Class对象的三种方式 package lianxiApril18; /** * 获取Class对象的三种方式 * 1 Object ——> getClass(); * 2 任何数据类型( ...
- I-team 博客的 gitlab-runner 持续集成实践
做为一个略微看过nodejs语法,但又不懂nodejs的攻城狮,搭建hexo环境很是麻烦,要考虑到FQ版本兼容等问题.于是乎,博主每换一个电脑,为了能继续发博客,都需要在新电脑上花一天时间重新搞一下 ...