生产者和消费者之间的线程通讯wait()
生产者与消费者,采用notify()唤醒
package com.dwz.concurrency.chapter9;
/**
* 生产者和消费者之间的通信问题
* 执行wait()之后锁被释放
*/
public class ProduceConsumerVersion4 {
private final Object LOCK = new Object();
private int i = 0;
private volatile boolean isProduced = false; private void produce() {
synchronized(LOCK) {
if(isProduced) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
i++;
System.out.println("p->" + i);
LOCK.notify();
isProduced = true;
}
}
} private void consumer() {
synchronized(LOCK) {
if(isProduced) {
System.out.println("c->" + i);
LOCK.notify();
isProduced = false;
} else {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试代码(一个生产者与一个消费者)
public static void main(String[] args) {
ProduceConsumerVersion4 pc = new ProduceConsumerVersion4();
new Thread("P") {
@Override
public void run() {
while(true) {
pc.produce();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread("C") {
@Override
public void run() {
while(true) {
pc.consumer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
测试结果是线程安全的,程序正常结束
测试代码(多个生产者与多个消费者)
public static void main(String[] args) {
ProduceConsumerVersion2 pc = new ProduceConsumerVersion2();
Stream.of("P1", "P2").forEach(n ->
new Thread(n) {
@Override
public void run() {
while(true) {
pc.produce();
}
}
}.start()
);
Stream.of("C1", "C2").forEach(n ->
new Thread(n) {
@Override
public void run() {
while(true) {
pc.consumer();
}
}
}.start()
);
}
测试结果:程序不能正常结束,被阻塞
多个生产者和多个消费者之间通信采用 notify()
缺点:会存在所有线程都等待的问题(wait)
分析:notify不能识别wait的身份,有可能消费者唤醒的是消费者,导致线程都blocked
改进方法,使用notifyAll()代替notify()
package com.dwz.concurrency.chapter9; import java.util.stream.Stream; /**
* 多个生产者和多个消费者之间通信(线程安全版)
*/
public class ProduceConsumerVersion3 {
private final Object LOCK = new Object();
private int i = 0;
private volatile boolean isProducted = false; private void produce() {
synchronized(LOCK) {
if(isProducted) {
try {
LOCK.wait();
return;
} catch (InterruptedException e) {
e.printStackTrace();
}
} i++;
System.out.println(Thread.currentThread().getName() + "for P->" + i);
LOCK.notifyAll();
isProducted = true;
}
} private void consumer() {
synchronized(LOCK) {
if(!isProducted) {
try {
LOCK.wait();
return;
} catch (InterruptedException e) {
e.printStackTrace();
}
} System.out.println(Thread.currentThread().getName() + "for C->" + i);
LOCK.notifyAll();
isProducted = false;
}
}
}
测试结果,程序是线程安全的,正常执行
The difference of sleep and wait
1.sleep is the method of Thread, but wait is the method of Object
2.sleep will not release the object monitor(Lock), but the wait will be release the monitor and add to the Object monitor waiting queue
3.use sleep not need depend on monitor, but wait need
4.The sleep method not need be wakeup, but wait method need.(besides wait(milons))
生产者和消费者之间的线程通讯wait()的更多相关文章
- JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止
JAVA之旅(十五)--多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止 我们接着多线程讲 一.生产者和消费者 什么是生产者和消费者?我们 ...
- JAVA笔记14__多线程共享数据(同步)/ 线程死锁 / 生产者与消费者应用案例 / 线程池
/** * 多线程共享数据 * 线程同步:多个线程在同一个时间段只能有一个线程执行其指定代码,其他线程要等待此线程完成之后才可以继续执行. * 多线程共享数据的安全问题,使用同步解决. * 线程同步两 ...
- 生产者与消费者+Queue(线程安全)
from queue import Queue from lxml import etree import requests from urllib import request from threa ...
- 多进程(了解):守护进程,互斥锁,信号量,进程Queue与线程queue(生产者与消费者模型)
一.守护进程 主进程创建守护进程,守护进程的主要的特征为:①守护进程会在主进程代码执行结束时立即终止:②守护进程内无法继续再开子进程,否则会抛出异常. 实例: from multiprocessing ...
- java 线程并发(生产者、消费者模式)
线程并发协作(生产者/消费者模式) 多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”. Ø 什么是生产者? 生产者指的是负责生产数 ...
- 线程操作案例--生产者与消费者,Object类对线程的支持
本章目标 1)加深对线程同步的理解 2)了解Object类中对线程的支持方法. 实例 生产者不断生产,消费者不断消费产品. 生产者生产信息后将其放到一个区域中,之后消费者从区域中取出数据. 既然生产的 ...
- python queue和生产者和消费者模型
queue队列 当必须安全地在多个线程之间交换信息时,队列在线程编程中特别有用. class queue.Queue(maxsize=0) #先入先出 class queue.LifoQueue(ma ...
- 守护进程,互斥锁,IPC,生产者与消费者模型
守护进程: b 进程守护 a进程,当a进程执行完毕时,b进程会跟着立马结束 守护进程用途: 如果父进程结束了,子进程无需运行了,就可以将子进程设置为父进程的守护进程 例如我们qq视频聊天时,当我们退出 ...
- go语言实现"生产者"和"消费者"的例子
学习java的多线程的时候最经典的一个例子就是生产者消费者模型的例子,最近在研究go语言协程,发现go提供的sync包中有很多和java类似的锁工具,尝试着用锁工具配合协程实现一个"消费者& ...
随机推荐
- 图像识别tesseract-ocr
下载地址 https://github.com/tesseract-ocr/tesseract/wiki/Data-Files. https://github.com/tesseract-ocr/te ...
- Codeforces 1097E. Egor and an RPG game
传送门 首先考虑怎么算 $f(n)$ (就是题目里面那个 $f(n)$) 发现可以构造一组序列大概长这样: ${1,3,2,6,5,4,10,9,8,7,15,14,13,12,11,...,n(n+ ...
- Python如何将字符和Unicode编码转变
小小总结一下,以防过几天忘记,自己的复习资料,如果能帮到大家,也是有所作用!! 1,字符转化为Unicode编码方法: ord("字符") ord("A") o ...
- 关于工作单元模式——工作单元模式与EF结合的使用
工作单元模式往往和仓储模式一起使用,本篇文章讲到的是工作单元模式和仓储模式一起用来在ef外面包一层,其实EF本身就是工作单元模式和仓储模式使用的经典例子,其中DbContext就是工作单元,而每个Db ...
- arcgis js之调用wms服务
arcgis js之调用wms服务 定义: export const tdtlayer = async () => { let WMSLayer = await arcgisPackage.WM ...
- Vue中断axios请求-切换页面+重复请求
切换页面时中断 一.概述 在Vue单页面开发过程中,遇到这样的情况,当我切换页面时,由于上一页面请求执行时间长,切换到该页面时,还未执行完,这时那个请求仍会继续执行直到请求结束,此时将会影响页面性能, ...
- ES6-数组的扩展-整理
一.Array.from():负责把类似数组的对象以及可遍历的对象转为真正的数组 1.类似数组的对象 let arrayLike = { '0': 'a', '1': 'b', '2': 'c', l ...
- Webstorm2017.3.3软件的安装使用
下载 ▶进入jetbrains的官方网站点击download,即下载开始.官方网站链接:http://www.jetbrains.com/webstorm/ 安装 ▶双击刚下载完成的.exe文件开始进 ...
- Django_03_后台管理
后台管理 站点分为内容发布和公共访问两部分 内容发布的部分由网站的管理员负责查看.添加.修改.删除数据,开发这些重复的功能是一件单调乏味.缺乏创造力的工作,为此,Django能够根据定义的模型类自动地 ...
- 牛客练习赛53 D 德育分博弈政治课 (思维建图,最大流)
牛客练习赛53 D德育分博弈政治课 链接:https://ac.nowcoder.com/acm/contest/1114/D来源:牛客网 题目描述 德育分学长最近玩起了骰子.他玩的骰子不同,他的骰子 ...