条件阻塞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 ...
随机推荐
- 仿酷狗音乐播放器开发日志三——修复CEditUI的bug2
无意中发现了CEditUI控件的另一个bug,当我给播放器的搜索栏获取焦点时,这时再改变窗体大小,原本搜索栏应该对应着也改变大小,却发现CEditUI内嵌的edit控件没有跟着改变(如下图),跟着调试 ...
- 【原】Redis-LRU缓存
Redis高级篇 Redis-LRU缓存 将Redis作为缓存使用时,有时添加新数据时,旧数据是很难被清空的. LRU(Least Recently Used) 近期最少使用算法是常用算法之一. 最大 ...
- MMU(what,how,todo)
出处:http://www.100ask.org/bbs/forum.php?mod=viewthread&tid=11580&fromuid=5490 正文黑色,代码蓝色,重点标红. ...
- windows7 ubuntu双系统采用windows7 mbr引导方法
在安装有Windows7系统上的机器,安装用Ubuntu后,开机会自动用grub2 引导.对于使用双系统的用户来说,用MBR和grub2都差不多,但是,我的机器上有三个系统,需要用MBR来引导变色龙, ...
- uvalive 4670 Dominating Patterns
在文本串中找出现次数最多的子串. 思路:AC自动机模板+修改一下print函数. #include<stdio.h> #include<math.h> #include< ...
- C# 结构体保存自定义文件 实例部分代码(转)
http://www.cnblogs.com/jxsoft/archive/2011/08/26/2154705.html
- 广州大学华软软件学院——NA视频下载
准备工具: 360极速浏览器(不要认错图标了): 浏览器视频下载插件: 第一步:安装浏览器插件 1.打开浏览器 2.解压,找到插件文件: 3.把插件拖到浏览器中: 4.添加,然后就完成了插件安装 查看 ...
- leetcode@ [134] Gas station (Dynamic Programming)
https://leetcode.com/problems/gas-station/ 题目: There are N gas stations along a circular route, wher ...
- 在virtualbox上安装mac os mavericks遇到Missing Bluetooth Controller Transport问题解决办法
挂载 HackBoot_Mav.iso 作为光驱,启动在 磁盘选择 界面,选择磁盘后按空格键,输入 启动参数 -v -x(-x的意思是安全模式,不这样的话,有蓝牙驱动作怪, 会输出 [IOBlueto ...
- soliworks三维机柜布局(四)进入solidworks中三维布线
首先需要在solidworks electrical中创建solidworks装配体文件. 菜单栏:处理--solidworks机柜布局--勾选要创建的装配体--点击确定 在文件列表下右键装配体文件- ...