这2天学习多线程同步, 想结合ExecutorService 实现“1个生产者多个消费者”的应用, 失败了
程序思路:1个生产者 一次只能放一个鸡蛋到盘子里, 之后通知 多个消费者竞争来取
但结果是1.所有线程都在wait 并且 生产者也跑去拿鸡蛋 , 我云。这是ExecutorService托管线程的结果, 如何才能改正确呢
2.一共6个线程, FixedPoolSize是 5 , 第6个线程在什么状态才能进入就绪状态呢?
跪谢大家帮我瞧瞧了。
[code="java"]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();
}
}
}[/code]
错误的结果如下
[quote][color=red]pool-1-thread-1[/color] 放入鸡蛋No.1320394990548
盘子里的蛋个数 1
[color=red]pool-1-thread-1[/color] 拿到鸡蛋No.1320394990548
[color=red]pool-1-thread-1[/color] 在等待鸡蛋
pool-1-thread-4 在等待鸡蛋
pool-1-thread-5 在等待鸡蛋
pool-1-thread-3 在等待鸡蛋
pool-1-thread-2 在等待鸡蛋
[/quote]
把生存者包装一下,弄成一个操作,什么时候需要什么时候调用不就放进去了么,你说的有点不太明白,我不清楚你要达到什么效果。你把你场景还原下。我给你做个demo
[quote] if (eggs.size() > 0) {
try {
wait();
} catch (InterruptedException e) {
}
} [/quote]
容量只有1?生产者也等待?[quote] Object egg = (String)eggs.get(0);
eggs.clear();// 清空盘子 [/quote]
取一个就鸡飞蛋打?全没了?
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{
@Override
public void run() {
Double dvalue = Math.random();
Plate.queue.add(dvalue);
System.out.println("放入鸡蛋:"+dvalue);
}
}
class GetThread implements Runnable{
@Override
public 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 queue = new ConcurrentLinkedQueue();
}
[code="java"]
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{
@Override
public void run() {
Double dvalue = Math.random();
Plate.queue.add(dvalue);
System.out.println("放入鸡蛋:"+dvalue);
}
}
class GetThread implements Runnable{
@Override
public 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 queue = new ConcurrentLinkedQueue();
}
[/code]
[quote] 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);
}
} [/quote]
总共就下了一次蛋,应该是
[code="java"] public void run() {
while (true)
plate.putEgg(egg);
}[/code]
不多说了