下面的程序是生存者消费者问题,Mantous不能共享到两线程里面求指教!
import java.util.*;
public class ProducerAndConsumer {

List<Mantou> Mantous = Collections.synchronizedList(new ArrayList<Mantou>()); 
boolean isFool  = false;
boolean isEmpty = false;

public static void main(String[] args) {
new ProducerAndConsumer().produce();
new ProducerAndConsumer().consume();
}

public void produce() {
new Thread(new Producer(Mantous)).start();

}
public void consume() {
new Thread(new Consumer(Mantous)).start();
}

public void put(Mantou m) {
Mantous.add(m);
}
public void out(Mantou m) {
Mantous.remove(m);
}

class Producer implements Runnable {
List<Mantou> Mantous = null;
Producer(List<Mantou> Mantous) {
this.Mantous = Mantous;
}
public synchronized void run() {
while(!isFool) {
Mantou m = new Mantou(Mantous.size());
put(m);
System.out.println("生产了mantou" +Mantous.size() );
try {
wait(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if(Mantous.size() >=100) {
try {
isFool = true;
wait(1000);
isFool = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

class Consumer implements Runnable {
List<Mantou> Mantous = null;
Consumer(List<Mantou> Mantous) {
this.Mantous = Mantous;
}
public synchronized void run() {
while(!isEmpty) {
if(Mantous.isEmpty()) {
try {
wait(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("吃掉了mantou" + Mantous.size());
Mantou m = Mantous.get(Mantous.size());
out(m);
try {
wait(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class Mantou {
int id;

Mantou(int id) {
this.id = id;
}
}
}
运行结果是只生产不消费,我觉得原因是Mantous没有共享到,但应该怎么共享呢?求各位前辈指教

解决方案 »

  1.   

    我先放一下我改的
    package thread.no1dog;import java.util.*;public class ProducerAndConsumer { List<Mantou> Mantous = Collections
    .synchronizedList(new ArrayList<Mantou>()); // boolean isFool = false;
    // boolean isEmpty = false; public static void main(String[] args) {
    ProducerAndConsumer p = new ProducerAndConsumer();
    p.produce();
    p.consume();
    } public void produce() {
    new Thread(new Producer(Mantous)).start(); } public void consume() {
    new Thread(new Consumer(Mantous)).start();
    } public void put() {
    synchronized (Mantous) {
    if (Mantous.size() < 100) {
    Mantous.add(new Mantou(Mantous.size()));
    System.out.println("生产了mantou" + Mantous.size());
    }
    }
    } public void out() {
    synchronized (Mantous) {
    if (Mantous.size() > 0) {
    Mantous.remove(Mantous.get(Mantous.size() - 1));
    System.out.println("吃掉了mantou" + Mantous.size());
    }
    }
    } class Producer implements Runnable {
    List<Mantou> Mantous = null; Producer(List<Mantou> Mantous) {
    this.Mantous = Mantous;
    } public void run() {
    while (true) {
    put();
    // 生产累死了,sleep
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    } class Consumer implements Runnable {
    List<Mantou> Mantous = null; Consumer(List<Mantou> Mantous) {
    this.Mantous = Mantous;
    } public void run() {
    while (true) {
    out();
    // 吃饱了,sleep
    try {
    Thread.sleep(500);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    } class Mantou {
    int id; Mantou(int id) {
    this.id = id;
    }
    }
    }
      

  2.   

    最主要问题几点new ProducerAndConsumer().produce(); 
    new ProducerAndConsumer().consume(); 这两个是不同的对象,
    List <Mantou> Mantous = Collections.synchronizedList(new ArrayList <Mantou>()); 
    会被创建两份。另外有一个bug
    Mantou m = Mantous.get(Mantous.size()); 
    这个错误。
    另外一般同步控制或者阻塞直接放在get put里就可以了,线程只负责送数据.因为比如你生产者线程生产好对象后,还要做很多操作,锁没有释放,消费线程没法干活了,所以尽量释放掉锁。
    实际应用remove会有个返回给消费者,然后做后面处理。
    其实我本来想写成阻塞的,但是你没这个要求后来去掉了。