JUC–保护性暂停
定义
即Guarded Suspension,用一个线程等待另一个线程的执行结果
要点
- 有一个结果需要从一个线程传递到另一个线程,让他们关联同一个GuardedObject
- 如果有结果不断从一个线程到另一个线程那么可以使用消息队列(见生产者/消费者)
- JDK中,join的实现、Future的实现,采用的就是此模式
- 因为要等待另一方的结果,因此归类到同步模式
- 底层就是:wait()+ notify()
实现
GuardedObject
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
| public 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 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class Test { public static void main(String[] args) { GuardedObject go = new GuardedObject();
new Thread(() -> { System.out.println("等待结果..."); Object res = go.get(); System.out.println("收到结果:" + res); }).start();
new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) {} go.complete("我是执行结果!"); System.out.println("已产生结果"); }).start(); } }
|
扩展_增加超时
不让线程无限等,最多等一段时间,没结果就返回null
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
| public class GuardedObject { private Object response;
public Object get(long maxWait) { long begin = System.currentTimeMillis(); long waitTime = 0;
synchronized (this) { while (response == null) { long needWait = maxWait - waitTime; if (needWait <= 0) { break; }
try { this.wait(needWait); } catch (InterruptedException e) {}
waitTime = System.currentTimeMillis() - begin; } return response; } }
public void complete(Object response) { synchronized (this) { this.response = response; this.notifyAll(); } } }
|
使用
1
| Object res = go.get(2000);
|
扩展_解耦等待和生产
如果需要在多个类之间使用GuardedObject对象,作为参数传递不是很方便,因此设计一个用来解耦的中间类,这样不仅能够解耦【结果等待者】和【结果生产者】,还能够同时支持多个任务的管理
设计思路: