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