问题描述
这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();// 清空盘子 取一个就鸡飞蛋打?全没了?