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. RabbitMQ和Kafka,更加便捷高效的消息队列使用方式,请放心食用

    一.RabbitMQ实例介绍RabbitMQ实例由华为云分布式消息服务(DMS)团队打造,实例采用物理隔离的方式部署,租户独占RabbitMQ实例.一键式部署,完全兼容开源RabbitMQ的使用方式, ...

  2. 程序员应该懂的ip地址知识汇总

    1.A类ip由1字节(1字节是8位2进制数)的网络地址和3字节的主机地址组成,网络地址最高位必须是0,地址范围是从1.0.0.0到126.0.0.0,所以A类网络地址有126个,每个网络能容纳至少2^ ...

  3. Spark概述及集群部署

    Spark概述 什么是Spark (官网:http://spark.apache.org) Spark是一种快速.通用.可扩展的大数据分析引擎,2009年诞生于加州大学伯克利分校AMPLab,2010 ...

  4. c++ undefinede reference to 构造函数/析构函数

    g++编译器问题 把头文件"a.h"和头文件实现文件"a.cpp"都include就解决了.

  5. WinForm中从SQLite数据库获取数据显示到DataGridView

    1.关于Sqlite Sqlite是一款开源的.适合在客户端和嵌入式设备中使用的轻量级数据库,支持标准的SQL. 不像SqlServer或Oracle的引擎是一个独立的进程.通过TCP或命名管道等与程 ...

  6. Visual Studio AI 离线模型训练(window 7)

    本篇博客用tensorflow训练自带的数据mnist,参考自博客. 背景: 搭建好AI环境:查看 window 7 64位 准备工作: 在搭建AI环境过程中下载的samples-for-ai不是最新 ...

  7. 【探路者】final贡献分配

     [探路者]组成员及各位博客地址. 1蔺依铭:http://www.cnblogs.com/linym762/ 2张恩聚:http://www.cnblogs.com/zej87/ 3米赫:http: ...

  8. Scrum Meeting 10.23

    Scrum Meeting No.3 今天所完成的任务仍然停留在学习基础知识上.说实话,由于缺少安卓开发.web开发的经验,我们只能一步步摸索着来. 成员 已完成任务 下一阶段任务 徐越 阅读网上的博 ...

  9. Chapter 6 面向对象基础

    面向对象=对象+类+继承+通信,如果一个软件系统采用这些概念来建立模型并给予实现,那么它就是面向对象的.面向对象的软件工程方法是面向对象方法在软件工程领域的全面运用涉及到从面向对象分析.面向对象设计. ...

  10. git学习-综合性文章

    文章:[转载]理解 Git 分支管理最佳实践 首先介绍了git各种分支: