引言

在写(五)java多线程之Lock类时,我们暂时忽略掉Lock的一个方法,那就是Lock.newCondition(),这个方法返回一个Condition,现在我们这章就重点讲这个东东是什么,以及怎么使用.

理论

Condition的中文翻译是状态.没错,这个就是让多线程在不同状态切换其他线程执行.跟Object.wait和Object.notify有点类似.

Condition.await: 让当前线程一直等到直到获取信号,或者发生中断.通过和lock锁互相配合,会使当前线程一直睡眠直到一下四种情况的其中一种发生:

另外一个线程调用当前Condition的signal方法,这当前线程会被挑选出来,并被唤醒

其他线程调用了当前Condition的signalAll方法

其他线程调用了当前线程的中断,这当前中断会被挂起

当前线程被假唤醒

Condition.awaitUninterruptibly 跟Condition.await类似,只是不能被中断

Condition.await(long time, TimeUnit unit) 当前线程会被唤醒,要么是获得信号,要么是中断,要么是指定时间到

Condition.awaitUntil(Date deadline)当前线程会被唤醒,要么是获得信号,要么是中断,要么是到了指定结束时间

一般用法如下

boolean aMethod(Date deadline) {

boolean stillWaiting = true;

lock.lock();

try {

while (!conditionBeingWaitedFor()) {

if (!stillWaiting)

return false;

stillWaiting = theCondition.awaitUntil(deadline);

}

// ...

} finally {

lock.unlock();

}

}

Condition.signal 唤醒等待的线程.如果当前的condition有多个线程在等待的话,这会唤醒其中一,且这个线程在返回await前必须重新获得锁

'Condition.signalAll' 唤醒所有等待的线程.如果当前的condition有多个线程在等待,则所有的线程都会被唤醒,且这些被唤醒的线程必须在返回await之前重新获得锁

例子1

枯燥无聊的理论,看完之后就忘记,还是要写一个例子加深印象吧.这里我们还是用之前小明和小红谈人生,谈理想的例子继续说明吧

首先要中间人GrilProduct,花花公子PlayBoy和测试类TestMain,都是跟之前(三)java多线程之wait notify notifyAlljava多线程之wait notify notifyAll,md)一样,这里就不占用篇幅了

我们继续改写卧室Room类

public class Room {

Lock lock = new ReentrantLock();

Condition boyIsCome = lock.newCondition();

Condition girlIsCome = lock.newCondition();

private String gril = null;

public void makeGridInRoom(String gril){

lock.lock();

try {

while (this.gril != null){

System.out.println(gril + " 我的心在等待... 永远在等待.. " );

girlIsCome.await();

}

Thread.sleep(10);

this.gril = gril;

boyIsCome.signalAll();

} catch (InterruptedException e) {

e.printStackTrace();

}finally {

lock.unlock();

}

}

public void playWithGril(String boy){

lock.lock();

try {

while (this.gril == null){

System.out.println(boy + " 我的心在等待... 永远在等待.. " );

boyIsCome.await();

}

Thread.sleep(10);

System.out.println(boy + " play with " + this.gril);

Thread.sleep(500);

this.gril = null;

girlIsCome.signal();

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

}

运行一下,结果如下

小红1号 我的心在等待... 永远在等待..

小明0号 play with 小红0号

小明9号 我的心在等待... 永远在等待..

小明2号 我的心在等待... 永远在等待..

小明5号 我的心在等待... 永远在等待..

小明7号 我的心在等待... 永远在等待..

小明4号 我的心在等待... 永远在等待..

小明6号 我的心在等待... 永远在等待..

小明1号 我的心在等待... 永远在等待..

小明3号 我的心在等待... 永远在等待..

小明8号 我的心在等待... 永远在等待..

小红2号 我的心在等待... 永远在等待..

小明9号 play with 小红1号

小明2号 我的心在等待... 永远在等待..

小明5号 我的心在等待... 永远在等待..

小明7号 我的心在等待... 永远在等待..

小明4号 我的心在等待... 永远在等待..

小明6号 我的心在等待... 永远在等待..

小明1号 我的心在等待... 永远在等待..

小明3号 我的心在等待... 永远在等待..

小明8号 我的心在等待... 永远在等待..

小红3号 我的心在等待... 永远在等待..

小明2号 play with 小红2号

小明5号 我的心在等待... 永远在等待..

小明7号 我的心在等待... 永远在等待..

小明4号 我的心在等待... 永远在等待..

小明6号 我的心在等待... 永远在等待..

小明1号 我的心在等待... 永远在等待..

小明3号 我的心在等待... 永远在等待..

小明8号 我的心在等待... 永远在等待..

小红4号 我的心在等待... 永远在等待..

小明5号 play with 小红3号

小明7号 我的心在等待... 永远在等待..

小明4号 我的心在等待... 永远在等待..

小明6号 我的心在等待... 永远在等待..

小明1号 我的心在等待... 永远在等待..

小明3号 我的心在等待... 永远在等待..

小明8号 我的心在等待... 永远在等待..

小红5号 我的心在等待... 永远在等待..

小明7号 play with 小红4号

小明4号 我的心在等待... 永远在等待..

小明6号 我的心在等待... 永远在等待..

小明1号 我的心在等待... 永远在等待..

小明3号 我的心在等待... 永远在等待..

小明8号 我的心在等待... 永远在等待..

小红6号 我的心在等待... 永远在等待..

小明4号 play with 小红5号

小明6号 我的心在等待... 永远在等待..

小明1号 我的心在等待... 永远在等待..

小明3号 我的心在等待... 永远在等待..

小明8号 我的心在等待... 永远在等待..

小红7号 我的心在等待... 永远在等待..

小明6号 play with 小红6号

小明1号 我的心在等待... 永远在等待..

小明3号 我的心在等待... 永远在等待..

小明8号 我的心在等待... 永远在等待..

小红8号 我的心在等待... 永远在等待..

小明1号 play with 小红7号

小明3号 我的心在等待... 永远在等待..

小明8号 我的心在等待... 永远在等待..

小红9号 我的心在等待... 永远在等待..

小明3号 play with 小红8号

小明8号 我的心在等待... 永远在等待..

小明8号 play with 小红9号

跟之前的结果差不多.

例子2

这时候就有人质疑了,既然结果跟用Object.wait和Object.notify一样,那为什么要用这个呢?细心的读者可以发现了,每次运行,同一个小明可能和不同的小红谈人生和理想.这时候小明是很开心.但小红却不乐意,觉得小明太花心,太不专一,什么甜言蜜语都是骗人的.好,那我们现在就让小明专一.帮小红排除他们的烦恼.

这时候全部的类都要改造了,没办法小红太强势了

首先我们改造一下中间人GrilProduct,让每一个小红都自带编号进入卧室等候

public class GrilProduct implements Runnable{

private Room room;

public GrilProduct(Room room) {

this.room = room;

}

@Override

public void run() {

for (int i = 0; i < 10; i ++){

room.makeGridInRoom("小红" + i + "号", i);

}

}

}

之后我们改造花花公子,他们进入房间时,要拿着小红对应的编号进入

public class PlayBoy implements Runnable{

private Room room;

private String boy;

private int index;

public PlayBoy(Room room, String boy, int index) {

this.room = room;

this.boy = boy;

this.index = index;

}

@Override

public void run() {

room.playWithGril(boy, index);

}

}

之后就是要改写卧室类Room了 ,让小红和小明的号码对应上,才让他们谈人生和理想,不然就让他们继续等待..

public class Room {

Lock lock;

List boyIsCome;

Condition girlIsCome;

private String gril = null;

private int index = -1;

public Room(){

lock = new ReentrantLock();

girlIsCome = lock.newCondition();

boyIsCome = new ArrayList<>();

for (int i = 0; i < 10; i ++){

boyIsCome.add(lock.newCondition());

}

}

public void makeGridInRoom(String gril, int index){

lock.lock();

try {

while (this.gril != null){

System.out.println(gril + " 我的心在等待... 永远在等待.. " );

girlIsCome.await();

}

Thread.sleep(10);

this.gril = gril;

this.index = index;

boyIsCome.get(index).signal();

} catch (InterruptedException e) {

e.printStackTrace();

}finally {

lock.unlock();

}

}

public void playWithGril(String boy, int index){

lock.lock();

try {

while (this.gril == null || this.index != index){

System.out.println(boy + " 我的心在等待... 永远在等待.. " );

boyIsCome.get(index).await();

}

Thread.sleep(10);

System.out.println(boy + " play with " + this.gril);

Thread.sleep(500);

this.gril = null;

this.index = -1;

girlIsCome.signal();

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

}

最后改写我们的测试类TestMain

public class TestMain {

public static void main(String[] args) {

Room room = new Room();

Thread grilProduct = new Thread(new GrilProduct(room));

Set boyThread = new HashSet<>();

for (int i = 0; i < 10; i ++){

boyThread.add(new Thread(new PlayBoy(room, "小明" + i + "号", i)));

}

grilProduct.start();

for (Thread boy : boyThread){

boy.start();

}

}

}

运行一下,结果如下:

小红1号 我的心在等待... 永远在等待..

小明9号 我的心在等待... 永远在等待..

小明0号 play with 小红0号

小明2号 我的心在等待... 永远在等待..

小明5号 我的心在等待... 永远在等待..

小明7号 我的心在等待... 永远在等待..

小明4号 我的心在等待... 永远在等待..

小明6号 我的心在等待... 永远在等待..

小明1号 我的心在等待... 永远在等待..

小明3号 我的心在等待... 永远在等待..

小明8号 我的心在等待... 永远在等待..

小红2号 我的心在等待... 永远在等待..

小明1号 play with 小红1号

小红3号 我的心在等待... 永远在等待..

小明2号 play with 小红2号

小红4号 我的心在等待... 永远在等待..

小明3号 play with 小红3号

小红5号 我的心在等待... 永远在等待..

小明4号 play with 小红4号

小红6号 我的心在等待... 永远在等待..

小明5号 play with 小红5号

小红7号 我的心在等待... 永远在等待..

小明6号 play with 小红6号

小红8号 我的心在等待... 永远在等待..

小明7号 play with 小红7号

小红9号 我的心在等待... 永远在等待..

小明8号 play with 小红8号

小明9号 play with 小红9号

恩小明和小红终于配对了,妈妈再也不用我被小红们追着打了,不过,小明们,我就对不住你们了.~~

打赏

如果觉得我的文章写的还过得去的话,有钱就捧个钱场,没钱给我捧个人场(帮我点赞或推荐一下)

java 线程condition_(七)java多线程之Condition相关推荐

  1. Java线程池七个参数详解

    java多线程开发时,常常用到线程池技术,这篇文章是对创建java线程池时的七个参数的详细解释. 从源码中可以看出,线程池的构造函数有7个参数,分别是corePoolSize.maximumPoolS ...

  2. Java线程池七个参数详解:核心线程数、最大线程数、空闲线程存活时间、时间单位、工作队列、线程工厂、拒绝策略

    源码简介 ThreadPoolExecutor是JDK中的线程池实现,这个类实现了一个线程池需要的各个方法,它提供了任务提交.线程管理.监控等方法. 下面是ThreadPoolExecutor类的构造 ...

  3. Java线程新特征——Java并发库

    一.线程池   Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定 ...

  4. java线程睡眠分析,java线程睡眠有关问题

    java线程睡眠问题 这是我的代码 package org.com.JframeDemo; public class ControlClass { private int readCount; //  ...

  5. java 线程_理解java多线程

    树枝头玩魔法班卓琴弦乐器的生物与发光的蝴蝶,数字艺术风格,插画绘画creature with java多线程 1.实现Runnable接口相比于继承Thread类: (1)适合多个相同的程序代码的线程 ...

  6. 【java线程系列】java线程系列之java线程池详解

    一线程池的概念及为何需要线程池: 我们知道当我们自己创建一个线程时如果该线程执行完任务后就进入死亡状态,这样如果我们需要在次使用一个线程时得重新创建一个线程,但是线程的创建是要付出一定的代价的,如果在 ...

  7. java线程池测试,Java线程池【测试Markdown样式】

    Java 线程池 目录 重点关注几个问题: 线程池中线程的生命周期 线程池启动后,如何初始化工作线程 线程数如何变化 如何管理空闲的线程 提交任务给工作线程.到工作线程完成任务的过程 线程池内异常处理 ...

  8. java线程饥饿原理,Java线程饥饿和锁的公平性「译」

    一个线程因为被其它线程抢占了而分配不到时间片,这就是[饥饿].这个线程[饿的要死]因为只有别的线程可以得到CPU时间片,就它得不到.解决饥饿的方法叫着公平性--所有的线程都有机会得到运行. 线程饥饿的 ...

  9. java线程安全的set_Java并发编程之set集合的线程安全类你知道吗

    Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥并发编程学习>系列之<并发集合系列& ...

  10. java 线程僵死_一次线上jboss僵死问题分析

    问题再现: 个人中心在上周四上线(2012.9.13)第一次上线,由于种种缘由,遗留了部分低级别的BUG,后于次日修复,下午4时再次上线. 当日晚上8点,运维发现user-web 五台服务器中四台jb ...

最新文章

  1. SSH远程会话管理工具 - screen使用教程
  2. UVa1450 Airport(二分法)
  3. 导航狗IT周报-2018年05月18日
  4. Oracle的服务介绍以及正常运行必须启动的服务
  5. php中的css类怎么查找,CSS 样式表中的类和伪类
  6. 【Vue.js 知识量化】基础语法
  7. sql/plus 常用操作
  8. vc access mysql_VC中访问Access数据库的方法
  9. MyBatis中大于和小于号的转义写法
  10. html文件如何添加到.net项目中中,如何在.NET中添加对mshtml版本9的引用
  11. 几个实用又好看的纯css 按钮样式
  12. 计算机及网络方面的杂志,计算机类省级期刊
  13. 电脑如何做动态图 GIF表情包怎么制作
  14. linux 原路返回路由,linux – 根据服务将返回流量路由到正确的网关
  15. unity 刚体的运动 减速运动
  16. 云服务器系统结构图,云服务器系统结构图
  17. 《实战 Java 高并发程序设计》笔记——第3章 JDK 并发包(二)
  18. 【游戏设计模式】之二 论撤消重做、回放系统的实现:命令模式
  19. 劣质代码评析——《写给大家看的C语言书(第2版)》附录B之21点程序(二)
  20. bootstrapTable printThis打印插件 中 printThis.js中的一个buge

热门文章

  1. 如何写好一份专利交底书?
  2. 七月算法机器学习 11 决策树、随机森林、 adaboost
  3. 学习笔记 再论静态方法和类方法
  4. 20191207每日一句
  5. Atitit java播放器调音速率快慢的实现 目录 1.1. 原理 本质上是改变采样率即可 1 2. 使用Java增加/降低AudioInputStream的音频播放速度(Increase/dec
  6. atitit.sql server2008导出导入数据库大的表格文件... oracle mysql
  7. paip. 混合编程的实现resin4 (自带Quercus ) 配置 php 环境
  8. paip.c++ cli 命令行 调用总结
  9. paip.项目文件同步-分支和合并总结V2012.9.23
  10. paip.软件及网站项目开发效率低下的思索与改进