定义
保护性暂停模式(Guarded Suspension Design Pattern):当线程在访问某个对象时,发现条件不满足时,就暂时挂起等待条件满足时再次访问。
要点:
- 有一个结果需要从一个线程传递到另一个线程,让他们关联同一个 GuardedObject
- 如果有结果不断从一个线程到另一个线程那么可以使用消息队列(见生产者/消费者)
- JDK 中,join 的实现、Future 的实现,采用的就是此模式
代码实现
public class GuardedObject<V> {
public V response;
public Object lock = new Object();
// 获取值
public V get() throws InterruptedException {
synchronized (lock) {
while (response == null) {
lock.wait();
}
}
return response;
}
// 带超时时间获取值
public V get(long mills) throws InterruptedException {
long start = System.currentTimeMillis();
synchronized (lock) {
while (response == null) {
// 剩下等待时长
long waitTime = start + mills - System.currentTimeMillis();
if (waitTime <= 0) {
// 超时直接退出
break;
}
lock.wait(waitTime);
}
}
return response;
}
// 设置值
public void set (V response) {
synchronized (lock) {
this.response = response;
lock.notifyAll();
}
}
}
测试
@Slf4j
class TestGuardedObejct {
public static void main(String[] args) {
GuardedObject<String> object = new GuardedObject<>();
// 线程1 设置值
new Thread(new Runnable() {
@Override
public void run() {
log.info("开始set");
try {
// 模拟超时任务
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
object.set("hello world!");
}
}).start();
// 线程2 获取值
new Thread(() -> {
try {
String str = object.get();
log.info("get到了值:{}", str);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}