ExecutorSerivce 实现1个生产者多个消费者问题--- 失败,求指教求回忆

问题描述

这2天学习多线程同步, 想结合ExecutorService 实现“1个生产者多个消费者”的应用, 失败了程序思路:1个生产者 一次只能放一个鸡蛋到盘子里, 之后通知 多个消费者竞争来取但结果是1.所有线程都在wait 并且 生产者也跑去拿鸡蛋 , 我云。这是ExecutorService托管线程的结果, 如何才能改正确呢2.一共6个线程, FixedPoolSize是 5 , 第6个线程在什么状态才能进入就绪状态呢?跪谢大家帮我瞧瞧了。 package stepbstep;import java.util.ArrayList;import java.util.List;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Plate {List<Object> eggs = new ArrayList<Object>();public synchronized Object getEgg() {if (eggs.size() == 0) {try {System.out.println(Thread.currentThread().getName()+" 在等待鸡蛋");wait();} catch (InterruptedException e) {}}System.out.println("盘子里的蛋个数 "+eggs.size());Object egg = (String)eggs.get(0);eggs.clear();// 清空盘子notify();// 唤醒阻塞队列的某线程到就绪队列System.out.println(Thread.currentThread().getName()+" 拿到鸡蛋"+egg);return egg;}public synchronized void putEgg(Object egg) {if (eggs.size() > 0) {try {wait();} catch (InterruptedException e) {}}eggs.add(egg);// 往盘子里放鸡蛋notifyAll();// 唤醒阻塞队列的某线程到就绪队列System.out.println(Thread.currentThread().getName()+" 放入鸡蛋"+egg);}static class AddThread extends Thread{private Plate plate;private Object egg=new String("No."+System.currentTimeMillis());public AddThread(Plate plate){this.plate=plate;}public void run(){plate.putEgg(egg);}}static class GetThread extends Thread{private Plate plate;public GetThread(Plate plate){this.plate=plate;}public void run(){for(int i=0;i<5;i++){plate.getEgg();}}}public static void main(String args[]){ExecutorService pool=null;try {pool = Executors.newFixedThreadPool(5);Plate plate=new Plate();Thread add=new Thread(new AddThread(plate));Thread get_2=new Thread(new GetThread(plate));Thread get_3=new Thread(new GetThread(plate));Thread get_4=new Thread(new GetThread(plate));Thread get_5=new Thread(new GetThread(plate));Thread get_6=new Thread(new GetThread(plate));pool.execute(add);pool.execute(get_2);pool.execute(get_3);pool.execute(get_4);pool.execute(get_5);pool.execute(get_6);} catch (Exception e) {e.printStackTrace();}finally{pool.shutdown();}}}错误的结果如下引用

解决方案

把生存者包装一下,弄成一个操作,什么时候需要什么时候调用不就放进去了么,你说的有点不太明白,我不清楚你要达到什么效果。你把你场景还原下。我给你做个demo
解决方案二:
引用 static class AddThread extends Thread{ private Plate plate; private Object egg=new String("No."+System.currentTimeMillis()); public AddThread(Plate plate){ this.plate=plate; } public void run(){ plate.putEgg(egg); } } 总共就下了一次蛋,应该是public void run() {while (true)plate.putEgg(egg);}不多说了
解决方案三:
package com.iteye.wenda;import java.util.concurrent.ConcurrentLinkedQueue;import java.util.concurrent.Executor;import java.util.concurrent.Executors;public class Wen_Synchronized_001 {public static void main(String[] args) {Executor executor = Executors.newFixedThreadPool(10);//启动5个取蛋的人 executor.execute(new GetThread());executor.execute(new GetThread());executor.execute(new GetThread());executor.execute(new GetThread());executor.execute(new GetThread());executor.execute(new GetThread());//放100个鸡蛋for(int i=0;i<10;i++){executor.execute(new AddThread());}}}class AddThread implements Runnable{@Overridepublic void run() {Double dvalue = Math.random();Plate.queue.add(dvalue);System.out.println("放入鸡蛋:"+dvalue);}}class GetThread implements Runnable{@Overridepublic void run() {while(true){Object egg = Plate.queue.poll();if(null!=egg){System.out.println("获得鸡蛋:"+egg);}else{try {Thread.sleep(1000l);} catch (InterruptedException e) {e.printStackTrace();}}}}}class Plate {public static ConcurrentLinkedQueue<Object> queue = new ConcurrentLinkedQueue<Object>();}
解决方案四:
package com.iteye.wenda;import java.util.concurrent.ConcurrentLinkedQueue;import java.util.concurrent.Executor;import java.util.concurrent.Executors;public class Wen_Synchronized_001 {public static void main(String[] args) {Executor executor = Executors.newFixedThreadPool(10);//启动5个取蛋的人 executor.execute(new GetThread());executor.execute(new GetThread());executor.execute(new GetThread());executor.execute(new GetThread());executor.execute(new GetThread());executor.execute(new GetThread());//放100个鸡蛋for(int i=0;i<10;i++){executor.execute(new AddThread());}}}class AddThread implements Runnable{@Overridepublic void run() {Double dvalue = Math.random();Plate.queue.add(dvalue);System.out.println("放入鸡蛋:"+dvalue);}}class GetThread implements Runnable{@Overridepublic void run() {while(true){Object egg = Plate.queue.poll();if(null!=egg){System.out.println("获得鸡蛋:"+egg);}else{try {Thread.sleep(1000l);} catch (InterruptedException e) {e.printStackTrace();}}}}}class Plate {public static ConcurrentLinkedQueue<Object> queue = new ConcurrentLinkedQueue<Object>();}
解决方案五:
引用 if (eggs.size() > 0) { try { wait(); } catch (InterruptedException e) { } } 容量只有1?生产者也等待?引用 Object egg = (String)eggs.get(0); eggs.clear();// 清空盘子 取一个就鸡飞蛋打?全没了?

时间: 2024-12-05 17:57:40

ExecutorSerivce 实现1个生产者多个消费者问题--- 失败,求指教求回忆的相关文章

activemq 实现多个生产者 多个消费者 同时操作一个队列应该怎么弄 求指导

问题描述 activemq 实现多个生产者 多个消费者 同时操作一个队列应该怎么弄 求指导 activemq 实现多个生产者 多个消费者 同时操作一个队列应该怎么弄 求指导 解决方案 http://blog.csdn.net/super_scan/article/details/39839145

leizi求指教-生产者消费者模式在什么情况下用到?

问题描述 生产者消费者模式在什么情况下用到? 生产者消费者通常都用来解决哪类问题?什么情况下需要想到用到生产者消费者模式呢? 解决方案 一般就是任务队列的时候,比如你有专门处理的任务的线程,同时有生成任务的线程,这样为了好控制,一般是把任务通过队列的方式来传递这样可以有多个线程做生产者,它们只需要把任务不停的丢入队列,同样很多线程做消费者,它们不停的从队列中取任务执行

聊聊并发:生产者消费者模式

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据.同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者.为了解决这个问题于是引入了生产者和消费者模式. 什么是生产者消费者模式 生产者

再谈线程:生产者与消费者

场景描述: 一个仓库,生产者在工厂里生产了产品后,将产品存放到仓库里,仓库存放数量有限,当满仓后,停 止生产,直到有消费着将产品消费后才继续生产:消费者从仓库里提取产品,当仓库空仓时,停止消费产 品,直到仓库中有产品时,才继续消费产品. 代码的实现(调整线程sleep时间可以实现生产速度与消费速度的不同): TestProduceAndConsumer.java package com.nantian; import java.util.Random; public class TestProd

聊聊并发(十)生产者消费者模式

本文首发于InfoQ   作者:方腾飞  校对:张龙 在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据.同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者.为了解决这种生产消费能力

Linux线程编程之生产者消费者问题

前言 本文基于顺序循环队列,给出Linux生产者/消费者问题的多线程示例,并讨论编程时需要注意的事项.文中涉及的代码运行环境如下: 本文假定读者已具备线程同步的基础知识. 一  顺序表循环队列 1.1 顺序循环队列定义 队列是一种运算受限的先进先出线性表,仅允许在队尾插入(入队),在队首删除(出队).新元素入队后成为新的队尾元素,元素出队后其后继元素就成为队首元素. 队列的顺序存储结构使用一个数组和两个整型变量实现,其结构如下: 1 struct Queue{ 2     ElemType el

java 生产者消费者问题 并发问题的解决(转)

引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品.互相等待,从而发生死锁. 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/

activemq-ActiveMQ生产者能查看当前消费者的ID或者查看有多少个消费者吗?

问题描述 ActiveMQ生产者能查看当前消费者的ID或者查看有多少个消费者吗? 最近刚接触ActiveMQ,想实现一个类似QQ好友上线提醒这样的功能,有什么方法可以获取当前连接的消费者呢?网上查资料好像JMX好像可以实现,但是我是用C#写的,C#有什么办法实现吗?各位大神求指教,小弟感激不尽!

生产者消费者问题-转自维基百科

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例.该问题描述了两个共享固定大小缓冲区的线程--即所谓的"生产者"和"消费者"--在实际运行时会发生的问题.生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程.与此同时,消费者也在缓冲区消耗这些数据.该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时