多生产者和多消费者是线程通信的经典案例,但是和生产者-消费者相比更为复杂,而且可能会产生程序假死。

public class Product {
private MyStack myStack; public Product(MyStack myStack) {
this.myStack = myStack;
} public void pushService(){
myStack.push();
}
} public class Consumer {
private MyStack myStack; public Consumer(MyStack myStack) {
this.myStack = myStack;
} public void popService(){
myStack.pop();
}
} public class ThreadP extends Thread {
private Product product; public ThreadP(Product product) {
this.product = product;
} @Override
public void run() {
while (true) {
product.pushService();
}
}
} public class ThreadC extends Thread{
private Consumer consumer; public ThreadC(Consumer consumer) {
this.consumer = consumer;
} @Override
public void run() {
while (true) {
consumer.popService();
}
}
} public class MyStack {
private List list = new ArrayList<>(); synchronized public void push() {
try {
while (list.size() == 1) {
this.wait();
}
list.add("anything=" + Math.random());
this.notifyAll();
System.out.println("push=" + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
} synchronized public String pop() {
String returnValue = "";
try {
while (list.size() == 0) {
System.out.println("pop wait begin"+Thread.currentThread().getName());
this.wait();
}
returnValue = "" + list.size();
list.remove(0);
Thread.sleep(1000);
this.notifyAll();
System.out.println("pop end"+list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnValue;
}
} /**
* Created by wangbin10 on 2018/7/10.
* 多生产多消费的情况程序运行后出现假死:
* 原因是虽然代码中已经wait/notify进行通信了,但是不能保证notify唤醒的就是是同类还是异类
* 可能会出现生产者唤醒生产者,消费者唤醒消费者的情况,长此以往,所有线程都进行等待
* 解决的办法就是将notify换成notifyAll
*/
public class Test {
public static void main(String[] args) {
MyStack myStack=new MyStack();
Product p1 = new Product(myStack);
Product p2 = new Product(myStack);
Product p3 = new Product(myStack);
Product p4 = new Product(myStack); ThreadP tp1=new ThreadP(p1);
ThreadP tp2=new ThreadP(p2);
ThreadP tp3=new ThreadP(p3);
ThreadP tp4=new ThreadP(p4); tp1.start();
tp2.start();
tp3.start();
tp4.start(); Consumer c1 = new Consumer(myStack);
Consumer c2 = new Consumer(myStack);
Consumer c3 = new Consumer(myStack);
Consumer c4 = new Consumer(myStack); ThreadC tc1 = new ThreadC(c1);
ThreadC tc2 = new ThreadC(c2);
ThreadC tc3 = new ThreadC(c3);
ThreadC tc4 = new ThreadC(c4); tc1.start();
tc2.start();
tc3.start();
tc4.start();
}
}

java多线程之多生产者-多消费者的更多相关文章

  1. java多线程中的生产者与消费者之等待唤醒机制@Version1.0

    一.生产者消费者模式的学生类成员变量生产与消费demo,第一版1.等待唤醒:    Object类中提供了三个方法:    wait():等待    notify():唤醒单个线程    notify ...

  2. Java多线程设计模式(2)生产者与消费者模式

    1 Producer-Consumer Pattern Producer-Consumer Pattern主要就是在生产者与消费者之间建立一个“桥梁参与者”,用来解决生产者线程与消费者线程之间速度的不 ...

  3. Java多线程与并发——生产者与消费者应用案例

    多线程的开发中有一个最经典的操作案例,就是生产者-消费者,生产者不断生产产品,消费者不断取走产品. package com.vince; /** * 生产者与消费者案例 * @author Admin ...

  4. java多线程中的生产者与消费者之等待唤醒机制@Version2.0

    二.生产者消费者模式的学生类成员变量生产与消费demo, @Version2.0 在学生类中添加同步方法:synchronized get()消费者,synchronized set()生产者 最终版 ...

  5. JAVA多线程经典问题 -- 生产者 消费者

    工作2年多来一直也没有计划写自己的技术博客,最近辞职在家翻看<thingking in JAVA>,偶尔看到了生产者与消费者的一个经典的多线程同步问题.本人在工作中很少使用到多线程以及高并 ...

  6. java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

    java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了  wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...

  7. Java多线程-并发协作(生产者消费者模型)

    对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一样,Hello World!都是最经典的例子. 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓 ...

  8. Java多线程14:生产者/消费者模型

    什么是生产者/消费者模型 一种重要的模型,基于等待/通知机制.生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几个点: ...

  9. java 线程并发(生产者、消费者模式)

    线程并发协作(生产者/消费者模式) 多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”. Ø 什么是生产者? 生产者指的是负责生产数 ...

随机推荐

  1. Qt5信号与槽C++11风格连接简介

    最近在论坛上看到了这个方面的问题,详见这里. 随后浅浅地学习了一下子,看到了Qt官方论坛上给出的说明,觉得C++11的functional连接方法还是比Qt4既有的宏连接方法有很大不同. 官方论坛的文 ...

  2. 5.1 入门整合案例(SpringBoot+Spring-data-elasticsearch) ---- good

    本节讲解SpringBoot与Spring-data-elasticsearch整合的入门案例. 一.环境搭建 新建maven项目,名字随意 pom.xml <parent> <gr ...

  3. jQuery迭代器

    http://www.imooc.com/code/3417 迭代器 迭代器是一个框架的重要设计.我们经常需要提供一种方法顺序用来处理聚合对象中各个元素,而又不暴露该对象的内部,这也是设计模式中的迭代 ...

  4. Redis入门手册

    这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么 2.redis的作者何许人也 3.谁在使用r ...

  5. C#中的字符串——用Stringbuilder类很重要

    注:这篇文章基本是<C#高级编程>(第七版)第九章的学习笔记. 众所周知,C#中处理字符串通常用的都是string,它其实是.NET基础类System.String类的映射.注意一个是小写 ...

  6. Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数

    作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ...

  7. 最新用WPF为触摸屏写了一个手写程序,双格输入的

    原文:最新用WPF为触摸屏写了一个手写程序,双格输入的 双格输入可以提高手写速度,当前字写完以后可以自动识别提交,写下一个字.这样比单格手写速度提高一倍.特别适合触摸屏程序使用 界面如下: 程序如下: ...

  8. [Gevent]gevent 网络抓取问答

    我听说过gevent基于事件的异步处理功能 如何高效率,该项目已很少使用,今天是没什么学习一些简单的使用. 有正式书面一个非常好的教程 中国版的地址:http://xlambda.com/gevent ...

  9. RDIFramework.NET框架SOA解(集Windows服务、WinForm形式和IIS发布形式)-分布式应用程序

    RDIFramework.NET框架SOA解决方式(集Windows服务.WinForm形式与IIS形式公布)-分布式应用 RDIFramework.NET,基于.NET的高速信息化系统开发.整合框架 ...

  10. x86汇编指令脚本虚拟机

    简介 这是一个可以直接解释执行从ida pro里面提取出来的x86汇编代码的虚拟机. 非常精简,整体架构上不能跟那些成熟的虚拟机相比,主要目标是够用.能用.轻量就行,如果觉得代码架构设计的不是很好的话 ...