0%

java | 设计模式 同步模式-保护性暂停

Guarded Suspension,用一个线程等待另一个线程的执行结果。

要点

  • 有一个结果需要从一个线程传递到另一个线程,让他们关联同一个 GuardedObject,生产结果和消费结果一一对应
  • 如果有结果不断从一个线程到另一个线程,那么,可以使用消息队列
  • JDK 中,join 的实现、Future 的实现,采用的就是此模式
  • 因为要等待另一方的结果,因此归类为同步模式

代码如下

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
package com.redisc;

import lombok.extern.slf4j.Slf4j;

class Downloader {
public static String download() throws InterruptedException {
Thread.sleep(2000);
return "success";
}
};

@Slf4j(topic = "c.Run")
public class Run {

public static void main(String[] args) throws Exception {
// 线程1 等待 线程2 的下载结果
GuardedObject guardedObject = new GuardedObject();
new Thread(() -> {
log.debug("等待结果");
Object state = (String) guardedObject.get();
log.debug("下载结果[{}]", state);
}, "t1").start();

new Thread(() -> {
log.debug("开始下载");
try {
String state = Downloader.download();
guardedObject.complete(state);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t2").start();
}

}

class GuardedObject {
private Object response;

// 获取结果
public Object get() {
synchronized (this) {
// 解决虚假唤醒
while (response == null) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return response;
}
}

// 产生结果
public void complete(Object response) {
synchronized (this) {
// 给结果成员变量赋值
this.response = response;
this.notifyAll();
}
}
}

输出

1
2
3
01:04:56.724 [t2] DEBUG c.Run - 开始下载
01:04:56.724 [t1] DEBUG c.Run - 等待结果
01:04:58.729 [t1] DEBUG c.Run - 下载结果[success]
请我喝杯咖啡吧~