Api文档如此定义:

ConditionObject 监视器方法(waitnotifynotifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。

Condition 接口描述了可能会与锁有关联的条件变量。这些变量在用法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的功能。需要特别指出的是,单个 Lock 可能与多个 Condition 对象关联。为了避免兼容性问题,Condition 方法的名称与对应的 Object 版本中的不同。
在 Condition 对象中,与 wait、notify 和 notifyAll 方法对应的分别是await、signal 和 signalAll。
Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得Condition 实例,请使用其 newCondition() 方法。

api相关方法:

  1. void await()造成当前线程在接到信号或被中断之前一直处于等待状态。
  2. boolean await(long time, TimeUnit unit) 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
  3. long awaitNanos(long nanosTimeout) 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
  4. void awaitUninterruptibly()造成当前线程在接到信号之前一直处于等待状态。
  5. boolean awaitUntil(Date deadline)造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。
  6. void signal()唤醒一个等待线程。
  7. void signalAll()唤醒所有等待线程。

例如:

package com.company;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /*
* 生产者消费者案例:
*/
public class TestProductorAndConsumerForLock { public static void main(String[] args) {
Clerk clerk = new Clerk(); Productor pro = new Productor(clerk);
Consumer con = new Consumer(clerk); new Thread(pro, "生产者 A").start();
new Thread(con, "消费者 B").start(); // new Thread(pro, "生产者 C").start();
// new Thread(con, "消费者 D").start();
} } class Clerk {
private int product = 0; private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition(); // 进货
public void get() {
lock.lock(); try {
if (product >= 1) { // 为了避免虚假唤醒,应该总是使用在循环中。
System.out.println("产品已满!"); try {
condition.await();//替代this.wait;
} catch (InterruptedException e) {
} }
System.out.println(Thread.currentThread().getName() + " : "
+ ++product); condition.signalAll();//代替this.notifyall();
} finally {
lock.unlock();
} } // 卖货
public void sale() {
lock.lock(); try {
if (product <= 0) {
System.out.println("缺货!"); try {
condition.await();//替代this.wait;
} catch (InterruptedException e) {
}
} System.out.println(Thread.currentThread().getName() + " : "
+ --product); condition.signalAll();//代替this.notifyall(); } finally {
lock.unlock();
}
}
} // 生产者
class Productor implements Runnable { private Clerk clerk; public Productor(Clerk clerk) {
this.clerk = clerk;
} @Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
} clerk.get();
}
}
} // 消费者
class Consumer implements Runnable { private Clerk clerk; public Consumer(Clerk clerk) {
this.clerk = clerk;
} @Override
public void run() {
for (int i = 0; i < 20; i++) {
clerk.sale();
}
} }

结果:

缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0
缺货!
生产者 A : 1
消费者 B : 0

java多线程 -- Condition 控制线程通信的更多相关文章

  1. Condition控制线程通信

    Condition控制线程通信 一.前言 java.util.concurrent.locks.Condition 接口描述了可能会与锁有关联的条件变量.这些变量在用法上与使用Object.wait ...

  2. Java核心知识点学习----使用Condition控制线程通信

    一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...

  3. 10. Condition 控制线程通信

    1. 是什么 ? 2. 示例 package com.gf.demo09; import java.util.concurrent.locks.Condition; import java.util. ...

  4. Java---Condition控制线程通信

    java中控制线程通信的方法有:1.传统的方式:利用synchronized关键字来保证同步,结合wait(),notify(),notifyAll()控制线程通信.不灵活. 2.利用Conditio ...

  5. java并发编程基础——线程通信

    线程通信 当线程在系统内运行时,程序通常无法准确的控制线程的轮换执行,但我们可以通过一些机制来保障线程的协调运行 一.传统的线程通信 传统的线程通信主要是通过Object类提供的wait(),noti ...

  6. Java多线程系列--“JUC线程池”02之 线程池原理(一)

    概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...

  7. Java多线程系列--“JUC线程池”03之 线程池原理(二)

    概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...

  8. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

  9. Java多线程——进程和线程

    Java多线程——进程和线程 摘要:本文主要解释在Java这门编程语言中,什么是进程,什么是线程,以及二者之间的关系. 部分内容来自以下博客: https://www.cnblogs.com/dolp ...

随机推荐

  1. ClassLoader.loadClass()与Class.forName()的区别

    ClassLoader.loadClass()与Class.forName()都是反射用来构造类的方法,但是他们的用法还是有一定区别的. 在讲区别之前,我觉得很有不要把类的加载过程在此整理一下. 在J ...

  2. ceilometer 源码分析(polling)(O版)

    一.简单介绍ceilometer 这里长话短说, ceilometer是用来采集openstack下面各种资源的在某一时刻的资源值,比如云硬盘的大小等.下面是官网现在的架构图 这里除了ceilomet ...

  3. python - 定时清理ES 索引

    只保留三天 #!/usr/bin/env python3 # -*- coding:utf-8 -*- import os import datetime # 时间转化为字符串 now_time = ...

  4. 最新!2016中国城市GDP排名出炉

    2017年1月20日,国家统计局公布:2016年中国国内生产总值GDP达744127亿元,同比增长6.7%,城市GDP方面:截至1月20日,全国大部分城市的去年经济运行数据已经公布,根据信息汇总,20 ...

  5. uniq命令详解

    基础命令学习目录首页 原文链接:http://man.linuxde.net/uniq 删除重复行: uniq file.txt sort file.txt | uniq sort -u file.t ...

  6. Flexbox + js实现滑动拼图游戏

    滑动拼图就是把一张图片分成几等份,打乱顺序(下图),然后通过滑动拼凑成一张完整的图片. 要实现一个拼图游戏,需要考虑怎样随机的打乱顺序,怎样交换两张图片的位置,等等.但是,使用了Flexbox布局以后 ...

  7. linux后退文件夹命令

    后退文件夹: cd -  在重复一遍就是前进了

  8. C++ 类 复制构造函数 The Copy Constructor

    一.复制构造函数的定义 复制构造函数是一种特殊的构造函数,具有一般构造函数的所有特性.复制构造函数创建一个新的对象,作为另一个对象的拷贝.复制构造函数只含有一个形参,而且其形参为本类对象的引用.复制构 ...

  9. 基于spec评论作品

    组名:杨老师粉丝群 组长:乔静玉 组员:吴奕瑶  刘佳瑞  公冶令鑫  杨磊  杨金铭  张宇  卢帝同 一.测试目标:拉格朗日2018——飞词 下面是他们的小游戏在运行时的一些截图画面: 1.开始: ...

  10. Daily Scrumming* 2015.10.31(Day 12)

    一.今明两天任务表 Member Today’s Task Tomorrow’s Task 江昊 学习rails的HTTP控制 继续学习rails等项目工具 杨墨犁 学习semanticUI的用法,配 ...