/* * 生产者与消费者问题 * 此问题用到Object类的wait(),notify() * 还要注意一个问题: * sleep()与wait()的区别: * sleep()过程中,对象仍未解锁 * wait ()过程中,对象解锁,其他线程可以访问当前对象,当唤醒时需重新锁定 */ public class Test { public static void main(String[] args) { ThingsStack ts = new ThingsStack(); Producer p = new Producer(ts); Consumer c = new Consumer(ts); new Thread(p).start(); new Thread(p).start(); new Thread(p).start(); new Thread(c).start(); new Thread(c).start(); new Thread(c).start(); } } class Things { int id; Things(int id) { this.id = id; } public String toString() { return "Things :" + id; } } class ThingsStack { int index = 0; Things [] arrThings = new Things[6]; public synchronized void push(Things t) { //if被打断后会跳出继续执行,用while语句更安全 // if(index == arrThings.length) { // try { // this.wait();//Object类的wait(); // } catch(InterruptedException e) { // e.printStackTrace(); // } // } while(index == arrThings.length) { try { this.wait();//Object类的wait(); } catch(InterruptedException e) { e.printStackTrace(); } } //this.notify(); this.notifyAll(); arrThings[index] = t; index ++; } public synchronized Things pop() { //if被打断后会跳出继续执行,用while语句更安全 // if(index == 0) { // try { // this.wait();//Object类的wait(); // } catch(InterruptedException e) { // e.printStackTrace(); // } // } while(index == 0) { try { this.wait();//Object类的wait(); } catch(InterruptedException e) { e.printStackTrace(); } } //this.notify(); this.notifyAll(); index --; return arrThings[index]; } } class Producer implements Runnable { ThingsStack ts = null; Producer(ThingsStack ts) { this.ts = ts; } public void run() { for(int i = 0; i < 20; i++) { Things t = new Things(i); ts.push(t); System.out.println("正在生产:" + t); try { Thread.sleep((int)Math.random() * 1000); } catch(InterruptedException e) { e.printStackTrace(); } } } } class Consumer implements Runnable { ThingsStack ts = null; Consumer(ThingsStack ts) { this.ts = ts; } public void run() { for(int i = 0; i < 20; i++) { Things t = ts.pop(); System.out.println("正在消费:" + t); try { Thread.sleep((int)Math.random() * 1000); } catch(InterruptedException e) { e.printStackTrace(); } } } }