条件阻塞Condition的应用
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* 有时候线程取得lock后需要在一定条件下才能做某些工作,比如说经典的Producer和Consumer问题。 在Java
* 5.0以前,这种功能是由Object类的wait(), notify()和notifyAll()等方法实现的,
* 在5.0里面,这些功能集中到了Condition这个接口来实现。
*/
public class ConditionTest { /**
* 篮子程序。Consumer必须在篮子里有苹果的时候才能吃苹果,否则它必须暂时放弃对篮子的锁定,
* 等到Producer往篮子里放了苹果后再去拿来吃。而Producer必须等到篮子空了才能往里放苹果,
* 否则它也需要暂时解锁等Consumer把苹果吃了才能往篮子里放苹果。
*/
public static class Basket {
// 锁
Lock lock = new ReentrantLock();
// 根据锁产生Condition对象
Condition produced = lock .newCondition();
Condition consumed = lock .newCondition();
// 篮子中的苹果数
int num = 0;
// 篮子中的最多放的苹果数
int count = 5; /**
* 生产苹果,往篮子里放
*
* @throws InterruptedException
*/
public void produce() throws InterruptedException {
// 获得锁
lock.lock();
System. out.println("Producer get a lock..." );
try {
// 判断是否满足生产条件
while (num == count) {
// 如果有苹果,则不生产,放弃锁,进入睡眠
// 等待消费者消费
System. out.println("Producer sleep..." );
consumed.await();
System. out.println("Producer awaked..." );
}
/* 生产苹果 */
Thread. sleep(new Random().nextInt(50));
System. out.println("Producer produced an Apple." );
num++;
System. out.println("Producer 篮子里有" + num + "个苹果" );
// 通知等待produced Condition的线程
produced.signal();
} finally {
lock.unlock();
}
} /**
* 消费苹果,从篮子中取
*
* @throws InterruptedException
*/
public void consume() throws InterruptedException {
// 获得锁
lock.lock();
System. out.println("Consumer get a lock..." );
try {
// 判断是否满足消费条件
while (num == 0) {
// 如果没有苹果,无法消费,则放弃锁,进入睡眠
// 等待生产者生产苹果
System. out.println("Consumer sleep..." );
produced.await();
System. out.println("Consumer awaked..." );
}
/* 吃苹果 */
Thread. sleep(new Random().nextInt(500));
System. out.println("Consumer consumed an Apple." );
num--;
System. out.println("Consumer 篮子里剩" + num + "个苹果" );
// 发信号唤醒某个等待consumed Condition的线程
consumed.signal();
} finally {
lock.unlock();
}
}
} /**
* 测试Basket程序
*/
public static void testBasket() throws Exception {
final Basket basket = new Basket();
// 定义一个producer
Runnable producer = new Runnable() {
public void run() {
try {
basket.produce();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}; // 定义一个consumer
Runnable consumer = new Runnable() {
public void run() {
try {
basket.consume();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}; // 各产生10个consumer和producer
ExecutorService service = Executors. newCachedThreadPool();
for (int i = 0; i < 10; i++) {
service.execute(producer);
}
for (int i = 0; i < 10; i++) {
service.execute(consumer);
}
service.shutdown();
} public static void main(String[] args) throws Exception {
ConditionTest. testBasket();
}
}
条件阻塞Condition的应用的更多相关文章
- 并发库应用之六 & 有条件阻塞Condition应用
Condition的功能类似在传统线程技术中的 Object.wait() 和 Object.natify() 的功能,传统线程技术实现的互斥只能一个线程单独干,不能说这个线程干完了通知另一个线程来干 ...
- python线程条件变量Condition(31)
对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition. 一.线程条件变 ...
- 竞态条件 race condition data race
竞态条件 race condition Race condition - Wikipedia https://en.wikipedia.org/wiki/Race_condition A race c ...
- [development][C] 条件变量(condition variables)的应用场景是什么
产生这个问题的起因是这样的: [:] <tong> lilydjwg: 主线程要启动N个子线程, 一个局部变量作为把同样的参数传入每一个子线程. 子线程在开始的十行会处理完参数. ...
- j.u.c系列(06)---之锁条件:Condition
写在前面 在没有Lock之前,我们使用synchronized来控制同步,配合Object的wait().notify()系列方法可以实现等待/通知模式.在Java SE5后,Java提供了Lock接 ...
- Linux组件封装(二)中条件变量Condition的封装
条件变量主要用于实现线程之间的协作关系. pthread_cond_t常用的操作有: int pthread_cond_init(pthread_cond_t *cond, pthread_conda ...
- python线程的条件变量Condition的用法实例
Condition 对象就是条件变量,它总是与某种锁相关联,可以是外部传入的锁或是系统默认创建的锁.当几个条件变量共享一个锁时,你就应该自己传入一个锁.这个锁不需要你操心,Condition 类会 ...
- threading 官方 线程对象和锁对象以及条件对象condition
官方地址:https://docs.python.org/2/library/threading.html#thread-objects 以下只截取condition部分,其他Lock()以及thre ...
- [转] 条件变量(Condition Variable)详解
http://www.wuzesheng.com/?p=1668 条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法.举个简单的例子,应用程序A ...
随机推荐
- HDU 5623KK's Number DP
题意:bc round 71 div 1 1003(有中文题面) 分析: 显然,每个人的策略就是都会拿剩下的数中最大的某几个数 假如我们用dp[i]表示当剩下i个数的时候先手得分-后手得分的最优值 那 ...
- linux删除数据文件无备份恢复
参考 : http://www.lunar2013.com/2013/06/linux-%E8%AF%AF%E5%88%A0%E9%99%A4%E6%96%87%E4%BB%B6%E6%81%A2%E ...
- 奇异秀App:奇异秀秀奇异,用大头视频来拜年
奇异秀APP是一款最新神奇的娱乐视频制作的手机应用软件,含有换头视频和特效视频两大特色功能,制作简单,效果酷炫,一键生成: 换头视频中可以由用户上传个人头像制作各种搞笑好玩的大头视频,有神曲.搞笑.节 ...
- FZU 2129 子序列个数
Problem Description 子序列的定义:对于一个序列a=a[1],a[2],......a[n].则非空序列a'=a[p1],a[p2]......a[pm]为a的一个子序列,其中1& ...
- 关于贴友的一个书本页面简单布局(html+css)的实现
贴友需求:以html+css仿照书本的页面实现布局效果(见图) html代码: 1: <!-- 我的博客:http://www.ido321.com --> DOCTYPE HTML> ...
- 安装sql server 出现挂起问题
1.安装SQL Server的时候出现的情况.“以前的某个程序已在安装计算机上创建挂起的文件操作.运行安装之前必须重新启动计算机”的提示. 2.解决方法 关于SQL安装被挂起的修复大家可能都遇到过当S ...
- C++&OpenCV中读取灰度图像到数组的两种
如标题所言,此处是对于灰度图像而言 ///method 1 read the image data one by one for (int row = 0, i = 0;row < imgDst ...
- 【noip2011】观光公交
题解: 做这题的时候为了敢速度- - 直接orz了神小黑的题解 其实我还是有想一个拙计的方法的- - dp:f[i][j] 表示到i点使用j个加速器 在i前上车的人的时间和 轻松愉悦转移之 - - 但 ...
- Raspberry Pi无线路由器篇
RaspberryPi可以折腾的方法很多,我将会吧自己的折腾经验与大家分享. 作为无线路由器,需要提供dhcp的功能和无线ap的能力,我们分别通过isc-dhcp-server和hostapd这两 ...
- 在KVM虚拟机中使用spice系列之二(USB映射,SSL,密码,多客户端支持)
在KVM虚拟机中使用spice系列之二(USB映射,SSL,密码,多客户端支持) 发布时间: 2015-02-27 00:16 1.spice的USB重定向 1.1 介绍 使用usb重定向,在clie ...