问题描述:生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加产品,消费者从存储空间中取走产品,当存储空间为空时,消费者阻塞,当存储空间满时,生产者阻塞
实现方法:使用synchronized关键字结合wait()和notify()实现
生产者代码:
1 class Producer implements Runnable{ 2 3 @Override 4 public void run() { 5 // TODO Auto-generated method stub 6 for(int i = 1;i <= 10; i++) { 7 System.out.println("生产者第" + i); 8 try { 9 Thread.sleep(1000); 10 } catch (InterruptedException e1) { 11 // TODO Auto-generated catch block 12 e1.printStackTrace(); 13 } 14 synchronized (lock) { 15 while(count >= max) { //防止假唤醒(唤醒之后发现条件不满足) 16 try { 17 lock.wait(); //释放锁 18 } catch (InterruptedException e) { 19 // TODO Auto-generated catch block 20 e.printStackTrace(); 21 } 22 } 23 count++; 24 System.out.println("生产者:" + Thread.currentThread().getName() + "完成生产:"+i+",当前count=" + count ); 25 lock.notifyAll(); 26 } 27 } 28 } 29 30 }
消费者代码:
1 class Consumer implements Runnable{ 2 3 @Override 4 public void run() { 5 // TODO Auto-generated method stub 6 for(int i = 1;i <= 10; i++) { 7 System.out.println("消费者第" + i); 8 try { 9 Thread.sleep(1000); 10 } catch (InterruptedException e1) { 11 // TODO Auto-generated catch block 12 e1.printStackTrace(); 13 } 14 synchronized (lock) { 15 while(count == 0) { //防止假唤醒(唤醒之后发现条件不满足) 16 try { 17 lock.wait(); //释放锁 18 } catch (InterruptedException e) { 19 // TODO Auto-generated catch block 20 e.printStackTrace(); 21 } 22 } 23 /*不要用if语句 24 if(count == 0) { 25 try { 26 lock.wait(); 27 } catch (Exception e) { 28 // TODO: handle exception 29 } 30 } 31 */ 32 count--; 33 System.out.println("消费者:" + Thread.currentThread().getName() + "完成消费"+i+",当前count=" + count ); 34 lock.notifyAll(); 35 } 36 } 37 } 38 39 }
运行主程序:
1 public static void main(String[] args) { 2 // TODO Auto-generated method stub 3 ConsumerAndProducer test = new ConsumerAndProducer(); 4 new Thread(test.new Producer(),"生产者1").start(); 5 new Thread(test.new Producer(),"生产者2").start(); 6 new Thread(test.new Producer(),"生产者3").start(); 7 new Thread(test.new Consumer(),"消费者1").start(); 8 new Thread(test.new Consumer(),"消费者2").start(); 9 new Thread(test.new Consumer(),"消费者3").start(); 10 }
输出:
生产者:生产者1完成生产:1,当前count=1 生产者:生产者2完成生产:1,当前count=2 生产者:生产者3完成生产:1,当前count=3 消费者:消费者3完成消费1,当前count=2 消费者:消费者2完成消费1,当前count=1 消费者:消费者1完成消费1,当前count=0 生产者:生产者1完成生产:2,当前count=1 生产者:生产者2完成生产:2,当前count=2 生产者:生产者3完成生产:2,当前count=3 消费者:消费者3完成消费2,当前count=2 消费者:消费者1完成消费2,当前count=1 消费者:消费者2完成消费2,当前count=0 生产者:生产者1完成生产:3,当前count=1 生产者:生产者3完成生产:3,当前count=2 生产者:生产者2完成生产:3,当前count=3 消费者:消费者2完成消费3,当前count=2 消费者:消费者1完成消费3,当前count=1 消费者:消费者3完成消费3,当前count=0 生产者:生产者1完成生产:4,当前count=1 生产者:生产者2完成生产:4,当前count=2 生产者:生产者3完成生产:4,当前count=3 消费者:消费者1完成消费4,当前count=2 消费者:消费者3完成消费4,当前count=1 消费者:消费者2完成消费4,当前count=0 生产者:生产者1完成生产:5,当前count=1 生产者:生产者2完成生产:5,当前count=2 生产者:生产者3完成生产:5,当前count=3 消费者:消费者3完成消费5,当前count=2 消费者:消费者1完成消费5,当前count=1 消费者:消费者2完成消费5,当前count=0 生产者:生产者1完成生产:6,当前count=1 生产者:生产者3完成生产:6,当前count=2 生产者:生产者2完成生产:6,当前count=3 消费者:消费者3完成消费6,当前count=2 消费者:消费者2完成消费6,当前count=1 消费者:消费者1完成消费6,当前count=0 生产者:生产者1完成生产:7,当前count=1 生产者:生产者2完成生产:7,当前count=2 生产者:生产者3完成生产:7,当前count=3 消费者:消费者3完成消费7,当前count=2 消费者:消费者2完成消费7,当前count=1 消费者:消费者1完成消费7,当前count=0 生产者:生产者1完成生产:8,当前count=1 生产者:生产者2完成生产:8,当前count=2 生产者:生产者3完成生产:8,当前count=3 消费者:消费者3完成消费8,当前count=2 消费者:消费者2完成消费8,当前count=1 消费者:消费者1完成消费8,当前count=0 生产者:生产者1完成生产:9,当前count=1 生产者:生产者3完成生产:9,当前count=2 生产者:生产者2完成生产:9,当前count=3 消费者:消费者3完成消费9,当前count=2 消费者:消费者1完成消费9,当前count=1 消费者:消费者2完成消费9,当前count=0 生产者:生产者1完成生产:10,当前count=1 生产者:生产者3完成生产:10,当前count=2 生产者:生产者2完成生产:10,当前count=3 消费者:消费者3完成消费10,当前count=2 消费者:消费者2完成消费10,当前count=1 消费者:消费者1完成消费10,当前count=0