concurrent(四)Condition
参考文档:
Java多线程系列--“JUC锁”06之 Condition条件:http://www.cnblogs.com/skywang12345/p/3496716.html
Condition介绍
Condition的作用是对锁进行更精确的控制。Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signalAll()相当于Object的notifyAll()方法。不同的是,Object中的wait(),notify(),notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的;而Condition是需要与"互斥锁"/"共享锁"捆绑使用的。基于Unsafe.park()/Unsafe.unpark()实现
Condition函数列表
// 造成当前线程在接到信号或被中断之前一直处于等待状态。
void await()
// 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
boolean await(long time, TimeUnit unit)
// 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
long awaitNanos(long nanosTimeout)
// 造成当前线程在接到信号之前一直处于等待状态。
void awaitUninterruptibly()
// 造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。
boolean awaitUntil(Date deadline)
// 唤醒一个等待线程。
void signal()
// 唤醒所有等待线程。
void signalAll()
举个栗子-单条件
public class ConditionTest {
private static Lock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
public static void main(String[] args) {
ThreadA ta = new ThreadA("t");
lock.lock(); // 获取锁
try {
System.out.println(Thread.currentThread().getName() + " start ta");
ta.start();
System.out.println(Thread.currentThread().getName() + " block");
condition.await(); // 等待
System.out.println(Thread.currentThread().getName() + " continue");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock(); // 释放锁
}
} static class ThreadA extends Thread {
public ThreadA(String name) {
super(name);
} public void run() {
lock.lock(); // 获取锁
try {
try {
Thread.sleep(1000*5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " wakup others");
condition.signal(); // 唤醒“condition所在锁上的其它线程”
} finally {
lock.unlock(); // 释放锁
}
}
}
}
举个栗子-多条件
/**
* 生产者消费者模型。一个lock,两个condition,一个condition控制消费者,一个condition控制生产者
* @author BFD_526
*
*/
public class ConditionMoreTest {
private static BoundedBuffer bb = new BoundedBuffer(); public static void main(String[] args) {
new PutThread("producer").start();
new TakeThread("consumer").start();
} static class PutThread extends Thread {
public PutThread(String name) {
super(name);
} public void run() {
while (true) {
try {
// 向BoundedBuffer中写入数据
Random rd = new Random();
bb.put(rd.nextInt(100));
Thread.sleep(1000*2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} static class TakeThread extends Thread {
public TakeThread(String name) {
super(name);
} public void run() {
while (true) {
try {
// 从BoundedBuffer中取出数据
Integer num = (Integer) bb.take();
//Thread.sleep(1000 * 3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
} class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
List<Integer> store = new ArrayList<Integer>();
int limitSize=5; public void put(Integer x) throws InterruptedException {
lock.lock(); // 获取锁
System.out.println("put start size:"+store.size());
try {
// 如果“缓冲已满”,则等待;直到“缓冲”不是满的,才将x添加到缓冲中。
while (store.size() == limitSize) {
System.out.println("buffer full wait " + Thread.currentThread().getName());
notFull.await();
}
// 将x添加到缓冲中
store.add(x);
// 唤醒take线程,因为take线程通过notEmpty.await()等待
notEmpty.signal();
System.out.println(Thread.currentThread().getName() + " put " + (Integer) x);
} finally {
lock.unlock(); // 释放锁
}
} public Object take() throws InterruptedException {
lock.lock(); // 获取锁
System.out.println("take start size:"+store.size());
try {
// 如果“缓冲为空”,则等待;直到“缓冲”不为空,才将x从缓冲中取出。
while (store.size() == 0)
notEmpty.await();
// 将x从缓冲中取出
Object x = store.remove(0);
// 唤醒put线程,因为put线程通过notFull.await()等待
notFull.signal();
// 打印取出的数据
System.out.println(Thread.currentThread().getName() + " take " + (Integer) x);
return x;
} finally {
lock.unlock(); // 释放锁
}
}
}
concurrent(四)Condition的更多相关文章
- 四、线程同步之Lock和Condition
Lock同步锁 Lock 在jdk1.5 提供了Lock以便执行同步操作,和synchronized不同的是Lock提供了显示的方法获取锁和释放锁.Lock提供了以下几个方法,请求和释放锁: voi ...
- 聊聊高并发(十四)理解Java中的管程,条件队列,Condition以及实现一个堵塞队列
这篇里面有一些主要的概念,理解概念是件有意义的事情,仅仅有理解概念才干在面对详细问题的时候找到正确的解决思路.先看一下管程的概念 第一次在书上看到管程这个中文名称认为非常迷糊,管程究竟是个什么东东,于 ...
- 使用Condition实现多线程之间调用(生产消费模式)
一,object 类的wait(),notify()和notifyAll() Java 线程类也是一个object 类,它的实例都继承自java.lang.Thread 或其子类.wait(),not ...
- ZooKeeper学习第四期---构建ZooKeeper应用
一.配置服务 配置服务是分布式应用所需要的基本服务之一,它使集群中的机器可以共享配置信息中那些公共的部分.简单地说,ZooKeeper可以作为一个具有高可用性的配置存储器,允许分布式应用的参与者检索和 ...
- JAVA基础学习之throws和throw的区别、Java中的四种权限、多线程的使用等(2)
1.throws和throw的区别 throws使用在函数外,是编译时的异常,throw使用在函数内,是运行时的异常 使用方法 public int method(int[] arr) throws ...
- Java并发之Condition
在使用Lock之前,我们使用的最多的同步方式应该是synchronized关键字来实现同步方式了.配合Object的wait().notify()系列方法可以实现等待/通知模式.Condition接口 ...
- [图解Java]Condition
图解Condition 0. demo 我先给出一个demo, 这样大家就可以根据我给的这段代码, 边调试边看源码了. 还是那句话: 注意"My" , 我把ReentrantLoc ...
- 并发之lock的condition接口
13.死磕Java并发-----J.U.C之Condition 12.Condition使用总结 11.Java并发编程系列之十七:Condition接口 === 13.死磕Java并发-----J. ...
- java Concurrent包学习笔记(三):ReentrantLock
一.可重入性的理解 从名字上理解,ReenTrantLock的字面意思就是再进入的锁,其实synchronized关键字所使用的锁也是可重入的,两者关于这个的区别不大.两者都是同一个线程每进入一次,锁 ...
- 使用Condition配合await()和signal()实现等待/通知
关键字Synchronized与wait()和notify()/notifyAll()结合可以实现“等待/通知”模式, Lock类的子类ReentrantLock也可以实现同样的功能,但需要借助Con ...
随机推荐
- thinkphp3.2 无法加载模块
当使用thinkphp3.2时候 出现一个无法加载模块的错误的时候 不要慌张,只需要在根目录下的 index.php 加入一句话就可 define('BIND_MODULE','Home'); // ...
- 【翻译】Tusdotnet中文文档(3)自定义功能和相关技术
自定义功能和相关技术 本篇按照如下结构翻译 自定义功能 自定义数据仓库 相关技术 架构和总体概念 自定义数据仓库 tusdotnet附带一个存储库TusDiskStore,它将文件保存在磁盘上的一个目 ...
- C# HttpWebRequest和WebClient的区别 通过WebClient/HttpWebRequest实现http的post/get方法
一 HttpWebReques1,HttpWebRequest是个抽象类,所以无法new的,需要调用HttpWebRequest.Create();2,其Method指定了请求类型,这里用的GET,还 ...
- OO第四单元作业小结
一.本单元两次作业的架构设计 1.第一次作业 整体思路:以class为核心,建立MyInterface.MyAttribute.MyOperation.MyAssociation四个类分别储存每个类的 ...
- vue单页面应用中动态修改title
https://www.jianshu.com/p/b980725b62e8 https://www.npmjs.com/package/vue-wechat-title 详细信息查看:vue-wea ...
- Jenkins 任务定时
在项目配置中选择 Build Triggers 下勾选 Build periodically,可以对项目进行定时构建设置.构建设置详细可通过右边的问号符号进行查看. 定时构建字段遵循 cron 的语法 ...
- JS 将数值取整为10的倍数
问题描述: 将数值处理为 10 的倍数,并支持向上或者向下取整 如将 2345 可以处理为 2300 | 2400 | 3000 | 2000 解决方案: /** * 将数字取整为10的倍数 * @p ...
- Java进程间通信学习
转自:https://www.iteye.com/blog/polim-1278435 进程间通信的主要方法有:(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共 ...
- 前端开发者必备的Nginx知识
摘要: 最常用的Web服务器 -- Nginx 原文:前端开发者必备的Nginx知识 作者:ConardLi Fundebug经授权转载,版权归原作者所有. Nginx在应用程序中的作用 解决跨域 请 ...
- csv数据的读取和写入,以及好看的可视化
参考: https://www.jianshu.com/p/5511cb3bdbb1 https://www.baidu.com/link?url=fbslMHoMviGOyn5Ub36VGdVQBD ...