生产者和消费者之间的线程通讯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类似的锁工具,尝试着用锁工具配合协程实现一个"消费者& ...
随机推荐
- MyBatis 源码篇-资源加载
本章主要描述 MyBatis 资源加载模块中的 ClassLoaderWrapper 类和 Java 加载配置文件的三种方式. ClassLoaderWrapper 上一章的案例,使用 org.apa ...
- 守护服务Supervisor的安装和使用
Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统 ...
- C# 委托 、事件、同步、异步知识点归纳
一.委托 基本用法: 1.声明一个委托类型.委托就像是‘类'一样,声明了一种委托之后就可以创建多个具有此种特征的委托.(特征,指的是返回值.参数类型) public delegate void Som ...
- USB相关资料汇总
[1]USB规范,一切的一切,基本的基本,天书级别USB_11_spec(中文).pdf USB1.1规范(中文版) usb_20.pdf USB2.0规 ...
- get_object_or_404返回404(400)
get_object_or_404:第一个参数为queryset,第二个参数必须以关键字的形式传递,否则报错
- 10.Spring整合Hibernate_3_HibernateTemplate
将sessionFactory 注入给 hibernateTemplate,让hibernateTemplate帮我们完成一些模板代码 <!-- 使用HibernateTemplate --&g ...
- PAT Basic 1082 射击比赛 (20 分)
本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军:谁差得最远,谁就是菜鸟.本题给出一系列弹洞的平面坐标(x,y),请你编写程序找出冠军和菜鸟.我们假设靶心在原点(0,0). 输入 ...
- java——maven依赖版本冲突
博客:maven依赖jar包时版本冲突的解决
- Keras---Virtualenv 下安装Keras (基于Tensorflow后端)
Python---Virtualenv 下安装Keras (基于Tensorflow后端) 一.Keras简介 https://keras-cn.readthedocs.io/en/latest ...
- 2018 牛客网暑期ACM多校训练营(第一场) E Removal (DP)
Removal 链接:https://ac.nowcoder.com/acm/contest/139/E来源:牛客网 题目描述 Bobo has a sequence of integers s1, ...