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 ...
随机推荐
- elasticsearch常用JAVA API 实例
1.引入dependency <dependency> <groupId>org.springframework.data</groupId> <artifa ...
- LightOJ 1098(均值不等式,整除分块玄学优化)
We all know that any integer number n is divisible by 1 and n. That is why these two numbers are not ...
- GitHub操作总结
GitHub操作总结 : 总结看不明白就看下面的详细讲解. . 作者:万境绝尘 转载请注明出处:http://blog.csdn.net/shulianghan/article/details/188 ...
- webUploader 的使用
地址:http://fex.baidu.com/webuploader/demo.html 这个主要是扒的demo 引用<link href="~/Scripts/webuploade ...
- Ocelot Consul
1首先创建一个json的配置文件,文件名随便取,我取Ocelot.json 这个配置文件有两种配置方式,第一种,手动填写 服务所在的ip和端口:第二种,用Consul进行服务发现 第一种如下: { & ...
- leecode刷题(12)-- 整数反转
leecode刷题(12)-- 整数反转 整数反转 描述: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: - ...
- PHP如何将多维数组中的数据批量插入数据库?
PHP将多维数组中的数据批量插入到数据库中,顾名思义,需要用循环来插入. 1.循环insert into 语句,逐渐查询 <?php /* www.qSyz.net */ @mysql_conn ...
- springmvc初步配置
导包/添加依赖: <dependency> <groupId>org.springframework</groupId> <artifactId>spr ...
- 论文阅读 | Region Proposal by Guided Anchoring
论文阅读 | Region Proposal by Guided Anchoring 相关链接 论文地址:https://arxiv.org/abs/1901.03278 概述 众所周知,anchor ...
- Behind the scenes of the C# yield keyword(转)
https://startbigthinksmall.wordpress.com/2008/06/09/behind-the-scenes-of-the-c-yield-keyword/ Behind ...