首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

线程共享有关问题,求前辈指教

2012-09-12 
线程共享问题,求前辈指教下面的程序是生存者消费者问题,Mantous不能共享到两线程里面求指教![codejava]im

线程共享问题,求前辈指教
下面的程序是生存者消费者问题,Mantous不能共享到两线程里面求指教!

[code=java]
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;
}
}
}


[/code]

运行结果是只生产不消费,我觉得原因是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().produce(); 
new ProducerAndConsumer().consume(); 

这两个是不同的对象,
List <Mantou> Mantous = Collections.synchronizedList(new ArrayList <Mantou>()); 
会被创建两份。

另外有一个bug
Mantou m = Mantous.get(Mantous.size()); 
这个错误。


另外一般同步控制或者阻塞直接放在get put里就可以了,线程只负责送数据.因为比如你生产者线程生产好对象后,还要做很多操作,锁没有释放,消费线程没法干活了,所以尽量释放掉锁。
实际应用remove会有个返回给消费者,然后做后面处理。
其实我本来想写成阻塞的,但是你没这个要求后来去掉了。

热点排行
Bad Request.