Java之多线程开发时多条件Condition接口的使用
转:http://blog.csdn.net/a352193394/article/details/39454157
我们在多线程开发中,可能会出现这种情况。就是一个线程需要另外一个线程满足某某条件才能继续运行,或者需
要其他线程满足好几个条件才能运行,对于这样的多条件的多线程并发,我们如何控制好各个线程之间的关系,使他们
能很好的处理冲突不至于相互出现问题呢,下面我们来介绍一下Java提供的Condition这个接口,这个接口很好的实现了
这种需求。
对于这个问题最经典的例子就是生产者消费者模型,生产者当缓冲区满的时候不生产商品知道缓冲区有空余,消费
者当缓冲区为0 的时候不拿商品,直到生产者向缓冲区放入商品,下面我们使用Conditon这个接口来实现这样的需求。
- 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();
- // 篮子中的苹果数,最多为1
- int num = 0;
- /**
- * 生产苹果,往篮子里放
- * @throws InterruptedException
- */
- public void produce() throws InterruptedException {
- // 获得锁
- lock.lock();
- System.out.println("Producer get a lock...");
- try {
- // 判断是否满足生产条件
- while (num == 1) {
- // 如果有苹果,则不生产,放弃锁,进入睡眠
- // 等待消费者消费
- System.out.println("Producer sleep...");
- consumed.await();
- System.out.println("Producer awaked...");
- }
- /*生产苹果*/
- Thread.sleep(500);
- System.out.println("Producer produced an Apple.");
- num = 1;
- // 通知等待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(500);
- System.out.println("Consumer consumed an Apple.");
- num = 0;
- // 发信号唤醒某个等待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();
- }
- }
- };
- // 各产生3个consumer和producer
- ExecutorService service = Executors.newCachedThreadPool();
- for (int i = 0; i < 3; i++){
- service.submit(producer);
- }
- for (int i = 0; i < 3; i++){
- service.submit(consumer);
- }
- service.shutdown();
- }
- public static void main(String[] args) throws Exception {
- ConditionTest.testBasket();
- }
- }
Java之多线程开发时多条件Condition接口的使用的更多相关文章
- 使用java做paypal开发时购买东西支付不成功的原因
使用java做paypal开发时购买东西支付不成功的原因 没有设置网站习惯设定,登陆自己的paypal账户,在网站习惯设定上填写回调的url路径,这样就可以 支付成功了并且异步修改订单的状态. 支付成 ...
- Java网络多线程开发:java.io.EOFException
Java网络多线程开发:java.io.EOFException 在实现韩顺平Java的多用户即使通信系统实战项目中: 对于客户端线程的停止,老韩是向服务器端发送一个消息对象,提示服务器端进行资源释放 ...
- Java Tread多线程(1)实现Runnable接口
作者 : 卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/39347245 本文演示,Tread多线程实现Runnable接口,以及简单 ...
- JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)
实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...
- 多线程之线程通信条件Condition
Condition是Locks锁下的还有一种线程通信之间唤醒.堵塞的实现.它以下的await,和signal可以实现Object下的wait,notify和notifyAll的所有功能,除此之外改监视 ...
- 多线程之线程通信条件Condition二
接上一篇,实现Condition三个条件,有这样一个应用: 1. 有三个进程,第一个进程运行1次,第二个进程运行2次,第三个进程运行3次: 2. 先运行第二个进程,然后第一个,然后第三个: 3. 依 ...
- java中多线程中测试某个条件的变化用 if 还是用 while?
最近在研究wait和notify方法,发现有个地方要注意,但是网上又说得不是很明白的地方,就是经典的生产者和消费模式,使用wait和notify实现,判断list是否为空的这个为什么要用while而不 ...
- sdk开发时,对外暴露的接口封装
思考,用同步还是异步? 实质就是屏蔽一些东西,让使用者直接传参数 拿结果 而不用关心具体实现 eg.登陆接口 1.定义接口LoginCallBack,两个函数 请求成功和失败 public inter ...
- JAVA之多线程的创建
转载请注明源出处:http://www.cnblogs.com/lighten/p/5967853.html 1.概念 老调重弹,学习线程的时候总会牵扯到进程的概念,会对二者做一个区分.网上有较多的解 ...
随机推荐
- mysql存储过程语法及实例
存储过程如同一门程序设计语言,同样包含了数据类型.流程控制.输入和输出和它自己的函数库. --------------------基本语法-------------------- 一.创建存储过程cr ...
- 新手如何查看API文档?
Java API文档为例: 1:知道包名,可以在Overview里直接找到这个包,然后去查这个包下面的类和方法.2:知道类名和方法名,可以在Index.html里直接去找这个类或方法,然后查看.3:如 ...
- ireport5.6+jasperreport6.3开发(三)--以javabean为基准的报表开发(javabean)
这里只有ireport的开发没有web侧的程序. ireport的数据源可以说是多种多样,大致可以通过文件 数据库 bean类这三种方式,这里只介绍bean类 (数据库比较简单可参考其他的网站,文件没 ...
- upupw一键绿色免安装环境包
项目测试,选择upupw环境包 下载nginx版本,解压即可使用 任务就是要把我电脑上的项目test.com提供给公司局域网同事访问,如果是apache的话,前面的wampserver已经讲过了. 1 ...
- autobench 测试笔记
yum install texinfo yum install gnuplot #下载 http://httperf.googlecode.com/files/httperf-0.9.0.tar.gz ...
- SEO之网站稳定
周未给大伙推荐个电影 :<环太平洋> http://947kan.com/movie/kehuan/45659/ 主要讲述了人类对抗从太平洋海底的时空裂缝不断传送过来的大怪兽,保卫家园的故 ...
- MVC MVP 和 MVVM的图示
一直对于这些什么MVC MVP 和 MVVM都是云里雾里的 完全分不清楚 感觉jq上也没怎么用过,理解也很片面,画几张图也许能够大体分清他们之间的区别. 1.MVC(Model-View-Contro ...
- H5如何实现一行三列布局
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF ...
- performSelector和performSelectorInBackground
前者是在主线程下完成的, 不会自动创建一个线程. 后者会创建一个新的线程.
- Command Pattern 命令模式
定义: 命令模式将‘请求’封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象,命令模式也支持可撤销的操作. 类图 如上图所示:Command类是用来声明执行操作的接口:ConcreteCom ...