保护性暂停,即Guarded Suspension,用一个线程等待另一个线程的执行结果
要点:
- 有一个结果需要从一个线程传递到另一个线程,让他们关联同一个GuardedObject
- 如果有结果不断从一个线程到另一个线程那么可以使用
消息队列
(见生产者/消费者) - JDK中,join的实现、Futrue的实现,采用的就是
此模式
- 因为要等待另一方的结果,因此归类到同步模式
代码实现
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class 保护性暂停 {
public static void main(String[] args) {
GuardedObject2 guardedObject2 = new GuardedObject2();
new Thread(() -> {
log.debug("begin");
Object response = guardedObject2.get(2000); //有时限的等待
log.debug("结果是:{}",response);
},"t1").start();
new Thread(() -> {
log.debug("begin");
try {
Thread.sleep(1000);
guardedObject2.complete(new Object()); //传递一个Object对象
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t2").start();
}
}
//此处理解为信箱
@Slf4j
class GuardedObject2{
//结果
private Object response;
//获取结果
//timeout 表示等待多久
public Object get(long timeout){
synchronized (this){
//开始时间
long begin = System.currentTimeMillis();
//经历的时间
long passTime = 0;
//没有结果
while(response == null){
//经历的时间超过了最大的等待时间,退出循环
if(passTime >= timeout){
break;
}
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
//求得经历时间
passTime = System.currentTimeMillis() - begin;
}
return response;
}
}
//产生结果
public void complete(Object response){
synchronized (this){
//给结果成员赋值
this.response = response;
this.notifyAll();
}
}
}
结果展示:
22:21:03.453 [t1] DEBUG 保护性暂停 - begin
22:21:03.453 [t2] DEBUG 保护性暂停 - begin
22:21:04.458 [t1] DEBUG 保护性暂停 - 结果是:java.lang.Object@7431101b