3、传统线程同步与通信--生产消费例子

核心点:

1、锁对象必须是同一个。
2、wait()和notify()方法必须是调用锁对象的方法,而非this(线程)的。
3、在多生产多消费的时候注意使用notifyAll而不是notifyAll,否则会造成死锁
4、将需要同步的多个方法尽量分布在同一个对象里。

测试代码:

  1 import java.util.LinkedList;
  2 import java.util.Queue;
  3 import java.util.Random;
  4 
  5 /**
  6  * 多个生产 - 消费 线程同步通信
  7  * 核心点:
  8  * 1、锁对象必须是同一个。
  9  * 2、wait()和notify()方法必须是调用锁对象的方法,而非this(线程)的。
 10  * 3、在多生产多消费的时候注意使用notifyAll而不是notifyAll
 11  * @author yzl
 12  *
 13  */
 14 public class ThreadPart_3 {
 15     public static void main(String[] args) {
 16         test();
 17     }
 18     public static void test(){
 19         final Factory factory = new Factory();
 20         Thread shengchan1 = new Thread(new Runnable() {
 21             @Override
 22             public void run() {
 23                 while(true){
 24                     factory.add();
 25                 }
 26             }
 27         });
 28         shengchan1.start();
 29         Thread shengchan2 = new Thread(new Runnable() {
 30             @Override
 31             public void run() {
 32                 while(true){
 33                     factory.add();
 34                 }
 35             }
 36         });
 37         shengchan2.start();
 38         
 39         Thread xiaofei1 = new Thread(new Runnable() {
 40             @Override
 41             public void run() {
 42                 while(true){
 43                     factory.sub();
 44 
 45                 }
 46             }
 47         });
 48         xiaofei1.start();
 49         Thread xiaofei2 = new Thread(new Runnable() {
 50             @Override
 51             public void run() {
 52                 while(true){
 53                     factory.sub();
 54                 }
 55             }
 56         });
 57         xiaofei2.start();
 58     }
 59 }
 60 
 61 class Factory{
 62     private Queue<Integer> queue = new LinkedList<Integer>();
 63     //生产
 64     public synchronized void add(){
 65         //用while代替if来防止假唤醒
 66         while(queue.size() > 0){
 67             try {
 68                 this.wait();
 69             } catch (InterruptedException e) {
 70                 e.printStackTrace();
 71             }
 72         }
 73         Integer val = new Random().nextInt(100);
 74         queue.add(val);
 75         System.out.println("生产者:" + Thread.currentThread().getName()+" add :" + val);
 76         this.notifyAll();
 77         try {
 78             Thread.sleep(1000);
 79         } catch (InterruptedException e) {
 80             e.printStackTrace();
 81         }
 82     }
 83     //消费
 84     public synchronized void sub(){
 85         //用while代替if来防止假唤醒
 86         while(queue.size() == 0 ){
 87             try {
 88                 this.wait();
 89             } catch (InterruptedException e) {
 90                 e.printStackTrace();
 91             }
 92         }
 93         Integer val = queue.poll();
 94         System.out.println("消费者:" + Thread.currentThread().getName()+" get : " + val);
 95         this.notifyAll();
 96         try {
 97             Thread.sleep(1000);
 98         } catch (InterruptedException e) {
 99             e.printStackTrace();
100         }
101     }
102 }

 运行结果示例:

 1 生产者:Thread-0 add :12
 2 消费者:Thread-3 get : 12
 3 生产者:Thread-1 add :84
 4 消费者:Thread-2 get : 84
 5 生产者:Thread-0 add :28
 6 消费者:Thread-3 get : 28
 7 生产者:Thread-1 add :60
 8 消费者:Thread-2 get : 60
 9 生产者:Thread-0 add :71
10 消费者:Thread-3 get : 71
11 生产者:Thread-1 add :63
12 消费者:Thread-3 get : 63
13 生产者:Thread-0 add :3
14 消费者:Thread-2 get : 3
15 生产者:Thread-1 add :62
16 消费者:Thread-3 get : 62
17 生产者:Thread-0 add :90
18 消费者:Thread-2 get : 90
19 生产者:Thread-1 add :9
20 消费者:Thread-3 get : 9
原文地址:https://www.cnblogs.com/yangzhilong/p/4764945.html