日期:2014-05-20  浏览次数:20667 次

关于消费者生产者存在一些有疑问的问题,麻烦大侠能解释解释!谢谢!
马士兵消费者生产者的源代码,初学时存在几点困惑,还望高手帮帮忙,不甚感激!!!
 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方法里面没有,还望赐教,谢谢
或者说怎样改才能使编译的结果正常化。

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