通知/等待机制有两种实现方式,一种是
wait/notify(notifyAll)
,一种是await/signal(signalAll)
下面我们对这两种方式进行展开
wait/notify(notifyAll)
字段 | 解释 |
---|---|
wait | 等待 |
notify | 随机唤醒一个等待线程 |
notifyAll | 唤醒所有等待线程 |
注意:wait/notify(notifyAll)需要搭配synchronized一起使用
代码示例
1package com.atguigu.juc.MyLock;
2
3public class ProductorAndCunstomer {
4
5 public static class Source {
6 private int number = 0;
7
8 // 生产
9 public synchronized void increatment() {
10 while (number != 0) {
11 try {
12 this.wait();
13 } catch (InterruptedException e) {
14 e.printStackTrace();
15 }
16 }
17 this.number++;
18 System.out.println(Thread.currentThread().getName() + "\t" + this.number);
19 this.notifyAll();
20 }
21
22 // 消费
23 public synchronized void decreatement() {
24 while (number == 0) {
25 try {
26 // 等待
27 this.wait();
28 } catch (InterruptedException e) {
29 e.printStackTrace();
30 }
31 }
32 this.number--;
33 System.out.println(Thread.currentThread().getName() + "\t" + this.number);
34 // 唤醒所有等待线程
35 this.notifyAll();
36 }
37 }
38
39
40 public static void main(String[] args) {
41 Source source = new Source();
42
43 new Thread(() -> {
44 for (int i = 0; i < 10; i++) {
45 source.increatment();
46 }
47 }, "A").start();
48
49 new Thread(() -> {
50 for (int i = 0; i < 10; i++) {
51 source.decreatement();
52 }
53 }, "B").start();
54
55 new Thread(() -> {
56 for (int i = 0; i < 10; i++) {
57 source.increatment();
58 }
59 }, "C").start();
60
61 new Thread(() -> {
62 for (int i = 0; i < 10; i++) {
63 source.decreatement();
64 }
65 }, "D").start();
66 }
67}
await/signal(signalAll)
字段 | 解释 |
---|---|
await | 线程等待 |
signal | 随机唤醒一个等待线程 |
signalAll | 唤醒所有等待线程 |
注意:await/signal(signalAll)需要搭配Lock一起使用
代码示例
1package com.atguigu.juc.MyLock;
2
3
4import java.util.concurrent.locks.Condition;
5import java.util.concurrent.locks.Lock;
6import java.util.concurrent.locks.ReentrantLock;
7
8public class ProductorAndCunstomer {
9
10 public static class Source {
11 private int number = 0;
12 private Lock lock = new ReentrantLock();
13 private Condition condition = lock.newCondition();
14
15 public void increatment() {
16 // 加锁
17 lock.lock();
18 try {
19 while (number != 0) {
20 // 等待
21 condition.await();
22 }
23 this.number++;
24 System.out.println(Thread.currentThread().getName() + "\t" + this.number);
25 condition.signalAll();
26
27 } catch (Exception e) {
28 e.printStackTrace();
29 } finally {
30 // 释放锁
31 lock.unlock();
32 }
33 }
34
35 public void decreatement() {
36 // 加锁
37 lock.lock();
38 try {
39 if (number == 0) {
40 // 等待
41 condition.await();
42 }
43 this.number--;
44 System.out.println(Thread.currentThread().getName() + "\t" + this.number);
45 // 通知
46 condition.signalAll();
47 } catch (Exception e) {
48 e.printStackTrace();
49 } finally {
50 // 释放锁
51 lock.unlock();
52 }
53 }
54 }
55
56
57 public static void main(String[] args) {
58 Source source = new Source();
59
60 new Thread(() -> {
61 for (int i = 0; i < 10; i++) {
62 source.increatment();
63 }
64 }, "A").start();
65
66 new Thread(() -> {
67 for (int i = 0; i < 10; i++) {
68 source.decreatement();
69 }
70 }, "B").start();
71
72 new Thread(() -> {
73 for (int i = 0; i < 10; i++) {
74 source.increatment();
75 }
76 }, "C").start();
77
78 new Thread(() -> {
79 for (int i = 0; i < 10; i++) {
80 source.decreatement();
81 }
82 }, "D").start();
83 }
84}
三角对应关系
![](https://i-blog.csdnimg.cn/blog_migrate/c155bc9e100d3f351f14259c1f475c59.png)
等待/通知机制告一段落~