java多线程 -- Condition 控制线程通信
Api文档如此定义:
Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 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相关方法:
- void await()造成当前线程在接到信号或被中断之前一直处于等待状态。
- boolean await(long time, TimeUnit unit) 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
- long awaitNanos(long nanosTimeout) 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
- void awaitUninterruptibly()造成当前线程在接到信号之前一直处于等待状态。
- boolean awaitUntil(Date deadline)造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。
- void signal()唤醒一个等待线程。
- 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 控制线程通信的更多相关文章
- Condition控制线程通信
Condition控制线程通信 一.前言 java.util.concurrent.locks.Condition 接口描述了可能会与锁有关联的条件变量.这些变量在用法上与使用Object.wait ...
- Java核心知识点学习----使用Condition控制线程通信
一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...
- 10. Condition 控制线程通信
1. 是什么 ? 2. 示例 package com.gf.demo09; import java.util.concurrent.locks.Condition; import java.util. ...
- Java---Condition控制线程通信
java中控制线程通信的方法有:1.传统的方式:利用synchronized关键字来保证同步,结合wait(),notify(),notifyAll()控制线程通信.不灵活. 2.利用Conditio ...
- java并发编程基础——线程通信
线程通信 当线程在系统内运行时,程序通常无法准确的控制线程的轮换执行,但我们可以通过一些机制来保障线程的协调运行 一.传统的线程通信 传统的线程通信主要是通过Object类提供的wait(),noti ...
- Java多线程系列--“JUC线程池”02之 线程池原理(一)
概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...
- Java多线程系列--“JUC线程池”03之 线程池原理(二)
概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...
- -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中
本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait( ...
- Java多线程——进程和线程
Java多线程——进程和线程 摘要:本文主要解释在Java这门编程语言中,什么是进程,什么是线程,以及二者之间的关系. 部分内容来自以下博客: https://www.cnblogs.com/dolp ...
随机推荐
- 如何配置php客户端(phpredis)并连接Redis--华为DCS for Redis使用经验系列
使用php连接Redis.Memcache等都需要进行扩展,以CentOS为例,介绍phpredis的客户端环境搭建. 第0步:准备工作 华为云上购买1台弹性云服务器ECS(我选了CentOS 6.3 ...
- Python常用模块之PIL(手册篇:Image模块)
官方手册地址:http://effbot.org/imagingbook/image.htm Image模块 图像模块提供了一个具有相同名称的类,用于表示一个PIL的图像.该模块还提供了许多功能,包 ...
- 用python实现数字图片识别神经网络--启动网络的自我训练流程,展示网络数字图片识别效果
上一节,我们完成了网络训练代码的实现,还有一些问题需要做进一步的确认.网络的最终目标是,输入一张手写数字图片后,网络输出该图片对应的数字.由于网络需要从0到9一共十个数字中挑选出一个,于是我们的网络最 ...
- web.xml配置文件中<async-supported>true</async-supported>报错
web.xml配置文件中<async-supported>true</async-supported>报错 http://blog.csdn.net/dream_ll/arti ...
- Alpha阶段展示报告
一.团队成员简介与个人博客地址 江昊,项目经理 http://www.cnblogs.com/haoj/ 王开,后端开发 http://www.cnblogs.com/wk1216123/ 王春阳,后 ...
- 20172324《Java程序设计》第二周学习总结
20172324<Java程序设计>第2周学习总结 教材学习内容总结 了解了字符串及其拼接和转义序列的使用. Java的基本数据类型. 定义数据转换类型和实现其转换的方法. Scanner ...
- 计算器简单封装和ASP.net
封装: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...
- Leetcode题库——11.盛最多水的容器
@author: ZZQ @software: PyCharm @file: maxArea.py @time: 2018/10/11 21:47 说明:给定 n 个非负整数 a1,a2,...,an ...
- Web应用程序的基本安全实践
创建安全Web应用程序的主题非常广泛.它需要研究以了解安全漏洞.您还需要熟悉Windows..NET框架和ASP.NET的安全设施.最后,有必要了解如何使用这些安全特性来对付威胁. 即使您没有安全方面 ...
- request使用代理
# *_*coding:utf-8 *_* import requests url = 'http://test.yeves.cn/test_header.php' params = {'id':'1 ...