读书人

关于消费者生产者存在一些有疑问的有关

发布时间: 2012-09-28 00:03:35 作者: rapoo

关于消费者生产者存在一些有疑问的问题,麻烦大侠能解释解释!谢谢!
马士兵消费者生产者的源代码,初学时存在几点困惑,还望高手帮帮忙,不甚感激!!!
public class ProducerConsumer {
public static void main(String[] args) {
SyncStack ss = new SyncStack();
Producer p = new Producer(ss);
Consumer c = new Consumer(ss);
new Thread(p).start();
//new Thread(p).start();
//new Thread(p).start();
new Thread(c).start();
}
}

class WoTou {
int id;
WoTou(int id) {
this.id = id;
}
public String toString() {
return "WoTou : " + id;
}
}

class SyncStack {
int index = 0;
WoTou[] arrWT = new WoTou[6];

public synchronized void push(WoTou wt) {
while(index == arrWT.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
arrWT[index] = wt;
index ++;
}

public synchronized WoTou pop() {
while(index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
index--;
return arrWT[index];
}
}

class Producer implements Runnable {
SyncStack ss = null;
Producer(SyncStack ss) {
this.ss = ss;
}

public void run() {
for(int i=0; i <20; i++) {
WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println("生产了:" + wt);
try {
Thread.sleep((int)(Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

class Consumer implements Runnable {
SyncStack ss = null;
Consumer(SyncStack ss) {
this.ss = ss;
}

public void run() {
for(int i=0; i <20; i++) {
WoTou wt = ss.pop();
System.out.println("消费了: " + wt);
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
生产了:WoTou : 17
消费了: WoTou : 17
生产了:WoTou : 18
消费了: WoTou : 18
生产了:WoTou : 19
消费了: WoTou : 19
消费了: WoTou : 11
消费了: WoTou : 4
消费了: WoTou : 3
消费了: WoTou : 2
消费了: WoTou : 1

输出完成 (耗时 12 秒) - 正常终止;
请问前辈,第一点:为什么push方法就直接是void push(WoTou wt) ,而pop方法要这样定义WoTou pop() ;
第二点,针对最后的结果,我百度查到的是这样说的,两个线程的run方法没有互斥。
你如果将打印语句放在WoTou wt = ss.pop();

pop()方法内部执行就行了。
但是,要怎么写进去,System.out.println("消费了" + wt);里面有个wt对象,但是pop方法里面没有,还望赐教,谢谢
或者说怎样改才能使编译的结果正常化。

------解决方案--------------------


1 push(WoTou wt)执行不需要返回值,你只要放进去就行了.(好像去银行存钱,存好就行了).
pop() 是取一个WoTou对象,执行完要返回一个WoTou对象的。(象取钱,你要实实在在拿到钱)。

2 arrWT[index]; 这就是那个对象。
你在返回前加一句:

Java code
System.out.println("消费了" + arrWT[index]);
[解决办法]
第一点:为什么push方法就直接是void push(WoTou wt) ,而pop方法要这样定义WoTou pop();
—— push是加入一个元素,只需要指定所需加入元素就行了,返回值没啥意义;
—— pop是弹出一个元素,弹出的规则是固定的,所以不需要参数,所弹出元素当然需要定义返回值,不然你怎么接收这个弹出元素?


第二点:
—— 没看懂你想问啥。。。


不过有个小Bug:
this.notifyAll();
建议应该放在
index ++; 或 index --; 之后

读书人网 >J2SE开发

热点推荐