为什么线程Consume 必须用构造啊?我把它改成new的形式就好使,谁能给我解释一下,谢谢!
public class PC { public static void main(String[] args) { Factory f = new Factory(); Producer p = new Producer(f); Consume c = new Consume(); new Thread(p).start(); new Thread(c).start(); } } //商品,货物 class Goods { int id; public Goods(int id) { this.id = id; } // 重写toString方法 public String toString() { return "Goods : " + id; } } class Factory { // 记录物品个数 int index = 0; Goods[] goods = new Goods[10]; // 制造方法,每次调用,增加一个商品 public synchronized void produce(Goods g) { //当容器已经满了,等待别人消费,wait,调用notify();等待别人消费后叫我再生产 while(index == goods.length){ try { this.wait();//Object类的wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); goods[index] = g; index++; } // 消费方法 public Goods consume() { synchronized (this) { //当容器没有商品了,等待生产者生产,自己wait,调用notify();等待别人生产后叫我去消费 while(index == 0){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); index--; return goods[index]; } } } class Producer implements Runnable { Factory f = null; public Producer(Factory f) { this.f = f; } public void run() { for (int i = 0; i < 50; i++) { Goods g = new Goods(i); f.produce(g); System.out.println("生产了:" + g); try {//生产一个睡一会儿 Thread.sleep((int) (Math.random() * 200)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consume implements Runnable { Factory f = null; // public Consume(Factory f){ // this.f = f; // } public void run() { for (int i = 0; i < 50; i++) { Goods g = new Goods(i); f = new Factory(); f.consume(); System.out.println("我消费了:" + g); try { Thread.sleep((int) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } }
[quote]
为什么线程Consume 必须用构造啊?
[/quote]
其实你问的问题与多线程无关。你的good实例是facotry#produce方法产生的,good的消费是facotry#consume方法消费的。你的线程无论是Producer还是Consume,都是通过调用facotry实例的相应方法来运行。所以你必须要传入facotry实例,要不然,他怎么知道是哪个facotry实例生产了good,你要消费哪个facotry实例的good
你说啥呢?没听懂
重新new Factory,它产生了一个新的实例对象,而通过构造方法创建,是传递之前的实例对象,两者是完全不一样的
如果你的Producer 是没有问题的,那么就是锁的问题。
Producer调用的方法是锁的方法public synchronized void produce(Goods g)
Consume调用的方法是在里面设置的同步块synchronized (this) { ,this指的是Factory,而你公用的是一个Factory,就没有排斥。
当你new的时候,在Consume里面都new了一个Factory,那么this就指向了不同的对象了,也就排斥了。
将consume也改成同步方法应该就没有问题了
:oops: 上面理解错了。
不过应该是锁的问题。。。。。要不就是我把lz题目理解错了~~~~~