JUC-Condition线程通信
1,Codition接口描述了可能会与锁有关联的条件变量。这些变量在用法上与使用Object.wait访问的隐式监视器类似。
但提供了更强大的功能,需要指出的是,单个lock可能与多个condition对象关联。为了避免兼容性问题,condition方法的名称与对应的object版本中不一样。
2,在condition对象中,与wait,notify,notifyAll方法对应的分别是await,signal,和signalAll。
3,condition实例实质上是被绑定到了一个锁上,要为特定Lock实例获得condition实例,请使用newCondition()方法。
针对上一节中使用synchronized和wait方法处理的生产者与消费者程序中,这里通过Lock和condition来联合处理。
要实现Lock和Condition处理,必须先实力化两个对象。
实例化Lock对象:
private Lock lock = new ReentrantLock();
实例化Condition对象:通过Lock对象的newCondition方法实例化,来获得Lock的锁,从而实现与Lock锁通信,进行唤醒,等待操作。
private Condition condition = lock.newCondition();
代码:
注意:await方法上一节的wait方法一致,需要放到while循环里面,避免被唤醒后条件不满足也继续执行。
package com.atguigu.juc;
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 {
while (product >= 1) { // 为了避免虚假唤醒,应该总是使用在循环中。
System.out.println("产品已满!");
try {
condition.await();
} catch (InterruptedException e) {
}
}
System.out.println(Thread.currentThread().getName() + " : "
+ ++product); condition.signalAll();
} finally {
lock.unlock();
}
} // 卖货
public void sale() {
lock.lock(); try {
while (product <= 0) {
System.out.println("缺货!");
try {
condition.await();
} catch (InterruptedException e) {
}
}
System.out.println(Thread.currentThread().getName() + " : "
+ --product); condition.signalAll(); } 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();
}
}
}
执行结果:
正常执行

JUC-Condition线程通信的更多相关文章
- Condition线程通信(七)
前言:对于线程通信,使用synchronized时使用wait.notify和notifyAll来实行线程通信.而使用Lock如何处理线程通信呢?答案就是本片的主角:Condition. 一.Cond ...
- 通过一道面试题了解Condition线程通信
Condition Condition接口描述了可能会与锁有关联的条件变量.这些变量在用法与使用Object.wait访问的隐式监视器类似,但提供了更强大的功能.需要特别指出的是,单个Lock可能与多 ...
- java 多线程 day13 condition 线程通信
/** * Created by chengtao on 17/12/5. * Condition 类似 wait和notify,解决线程间的同步问题 */ import java.util.conc ...
- Condition线程通信_生产者消费者案例
①Condition 接口描述了可能会与锁有关联的条件变量. 这些变量在用 法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的 功能. 需要特别指出的是,单个 Lock 可能与 ...
- JAVA基础知识之多线程——线程通信
传统的线程通信 Object提供了三个方法wait(), notify(), notifyAll()在线程之间进行通信,以此来解决线程间执行顺序等问题. wait():释放当前线程的同步监视控制器,并 ...
- JUC之线程间的通信
线程通信 视频1: 2021.12.18 JUC视频学习片段 对上次多线程编程步骤补充(中部): 创建资源类,在资源类中创建属性和操作方法 在资源类里面操作 判断 干活 通知 创建多个线程,调用资源类 ...
- JUC之线程间定制化通信
线程通信之定制化 之前文章中写了下Condition的使用,这里我们详细说下其中的用法: 首先使用Condition需要实例化Lock private Lock lock = new Reentran ...
- Java核心知识点学习----使用Condition控制线程通信
一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...
- 多线程之线程通信条件Condition
Condition是Locks锁下的还有一种线程通信之间唤醒.堵塞的实现.它以下的await,和signal可以实现Object下的wait,notify和notifyAll的所有功能,除此之外改监视 ...
- Condition控制线程通信
Condition控制线程通信 一.前言 java.util.concurrent.locks.Condition 接口描述了可能会与锁有关联的条件变量.这些变量在用法上与使用Object.wait ...
随机推荐
- 理解WebSocket心跳及重连机制(五)
理解WebSocket心跳及重连机制 在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件.这样会有:服务器会继续向客户端发送多余的 ...
- Objective-C 在main函数之前的过程
main函数是我们所熟知的程序入口,Java.Python.C++等,虽语法各异,但皆是如此.然而,程序真正的起点并非main函数,在此之前,就已经干了很多事情. 1.在main函数打个断点,从调用栈 ...
- php操作mysql使用的socket
在本地安装了php,安装了mysql,mysql-server.mysql服务也启动了. php扩展中也有mysql > php -m | grep mysql 然而执行mysql_connec ...
- python 取值方法:截取字符串
截取最后三位:aa=“TFR20171230001-1”cc=aa[-3]+aa[-2]+aa[-1] aa="1.36x36.8-ddr" bb=aa.split('x')[1] ...
- Luogu2336 SCOI2012 喵星球上的点名 SA、莫队
传送门 一道很套路的题目 先将所有串拼在一起,两个不同的串之间放一个没有出现在任何串中的字符做分隔,然后SA 那么对于所有点名串能够点到的名字串在SA中对应一段区间 把这些区间拿出来然后莫队统计每一个 ...
- LOJ564 613的天网 构造
题目传送门 题意:给出一个$N \times N \times N$的方块,你可以在每一个$1 \times 1 \times 1的方块上放上一个摄像头,摄像头的监视范围为6个方向的无限远距离.问最少 ...
- Java获取指定包名下的所有类的全类名的解决方案
最近有个需求需要获取一个指定包下的所有类的全类名,因此特意写了个获取指定包下所有类的全类名的工具类.在此记录一下,方便后续查阅 一.思路 通过ClassLoader来查找指定包 ...
- Quartz_简单使用
第一步:安装 新建一个QuartzDemo项目后,安装下面的程序包 Install-Package Quartz Install-Package Common.Logging.Log4Net1211 ...
- CentOS7中安装redis5.0
1. 环境介绍 CentOS7 (未安装Development Tools) 2. 下载Redis5.0-rc3 wget -O redis-5.0-rc3.tar.gz https://github ...
- 树莓派Opencv张正友棋盘标定法
make.Makefile cc = gcc #最简易的makefile文件,这个可以用来进行文件之间的简易构建和链接,生成我们所需要的执行文件: prom = calc deps = $(shell ...