代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
import java.util.LinkedList; import java.util.List; import java.util.Random; public class MyTest { private static int maxSize = 10; public static void main(String[] args) { LinkedList<Integer> storage = new LinkedList<Integer>(); Productor p1 = new Productor(storage, "1号生产者"); Productor p2 = new Productor(storage, "2号生产者"); Productor p3 = new Productor(storage, "3号生产者"); Consumer c1 = new Consumer(storage, "1号消费者"); Consumer c2 = new Consumer(storage, "2号消费者"); Thread t1 = new Thread(p1); Thread t2 = new Thread(p2); Thread t3 = new Thread(p3); Thread t4 = new Thread(c1); Thread t5 = new Thread(c2); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); }
static class Productor implements Runnable { private String name; private List<Integer> list; private Productor(List<Integer> list, String name) { this.list = list; this.name = name; } @Override public void run() { while (true) { synchronized (list) { while (list.size() >= maxSize) { System.out.println(name + "因空间不足,无法生产,进入等待"); try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } list.add(1); System.out.println(name + "生产了1个商品,现库存:" + list.size()); list.notifyAll(); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
static class Consumer implements Runnable { private String name; private List<Integer> list; private Consumer(List<Integer> list, String name) { this.list = list; this.name = name; } @Override public void run() { while (true) { synchronized (list) { while (list.size() == 0) { System.out.println(name + "因余量不足,无法消费,进入等待队列"); try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } list.remove(0); System.out.println(name + "消费了一个商品,现库存:" + list.size()); list.notifyAll(); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
|
代码中创建了 3 个生产者,2 个消费者,一直进行生产/消费行为。
并且设置仓储的最大容量为 10。
运行结果如下:
1号生产者生产了1个商品,现库存:1
2号生产者生产了1个商品,现库存:2
2号消费者消费了一个商品,现库存:1
3号生产者生产了1个商品,现库存:2
1号消费者消费了一个商品,现库存:1
2号生产者生产了1个商品,现库存:2
1号生产者生产了1个商品,现库存:3
1号消费者消费了一个商品,现库存:2
2号消费者消费了一个商品,现库存:1
3号生产者生产了1个商品,现库存:2
1号生产者生产了1个商品,现库存:3
2号生产者生产了1个商品,现库存:4
3号生产者生产了1个商品,现库存:5
1号消费者消费了一个商品,现库存:4
2号消费者消费了一个商品,现库存:3
1号生产者生产了1个商品,现库存:4
2号生产者生产了1个商品,现库存:5
2号消费者消费了一个商品,现库存:4
3号生产者生产了1个商品,现库存:5
1号消费者消费了一个商品,现库存:4
1号生产者生产了1个商品,现库存:5
2号生产者生产了1个商品,现库存:6
2号消费者消费了一个商品,现库存:5
3号生产者生产了1个商品,现库存:6
1号消费者消费了一个商品,现库存:5
2号生产者生产了1个商品,现库存:6
1号生产者生产了1个商品,现库存:7
1号消费者消费了一个商品,现库存:6
3号生产者生产了1个商品,现库存:7
2号消费者消费了一个商品,现库存:6
2号生产者生产了1个商品,现库存:7
1号生产者生产了1个商品,现库存:8
2号消费者消费了一个商品,现库存:7
3号生产者生产了1个商品,现库存:8
1号消费者消费了一个商品,现库存:7
2号生产者生产了1个商品,现库存:8
1号生产者生产了1个商品,现库存:9
3号生产者生产了1个商品,现库存:10
2号消费者消费了一个商品,现库存:9
1号消费者消费了一个商品,现库存:8
2号生产者生产了1个商品,现库存:9
1号生产者生产了1个商品,现库存:10
2号消费者消费了一个商品,现库存:9
3号生产者生产了1个商品,现库存:10
1号消费者消费了一个商品,现库存:9
2号生产者生产了1个商品,现库存:10
1号生产者因空间不足,无法生产,进入等待
3号生产者因空间不足,无法生产,进入等待
2号消费者消费了一个商品,现库存:9
1号消费者消费了一个商品,现库存:8
3号生产者生产了1个商品,现库存:9
1号生产者生产了1个商品,现库存:10
2号生产者因空间不足,无法生产,进入等待
1号消费者消费了一个商品,现库存:9
2号生产者生产了1个商品,现库存:10
3号生产者因空间不足,无法生产,进入等待
1号生产者因空间不足,无法生产,进入等待
2号消费者消费了一个商品,现库存:9
1号生产者生产了1个商品,现库存:10
3号生产者因空间不足,无法生产,进入等待
……
注意点
1、wait 外面一般要套用一个 while (条件判断)
如果不加,那么notify过早,线程会陷入等待;如果用 if(条件判断),那么线程在判断条件后,进入等待;这时条件已经被更改,该线程被唤醒后会继续执行,而不会重新判断是否符合现在的条件。
2、应使用 notifyAll 而不是 notify
如果仓储已满,而被唤醒的一直是生产者,那么所有线程都将陷入等待。
Reference
https://www.jianshu.com/p/e29632593057