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

关于消费者生产者存在一些有疑问的有关问题,麻烦大侠能解释解释!多谢

2012-09-28 
关于消费者生产者存在一些有疑问的问题,麻烦大侠能解释解释!谢谢!马士兵消费者生产者的源代码,初学时存在

关于消费者生产者存在一些有疑问的问题,麻烦大侠能解释解释!谢谢!
马士兵消费者生产者的源代码,初学时存在几点困惑,还望高手帮帮忙,不甚感激!!!
 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 --; 之后 

热点排行