1.Guarded Suspension,用在一个线程等待另一个线程的执行结果。
2.一个结果从一个线程传递到另一个线程,让他们关联同一个GuardedObject 保护对象。
3.如果有结果不断从一个线程到另一个线程,那么可以使用消息队列。
4.join方法和Future的实现,采用的就是此模式。
5.因为要等待另一方的结果,因此归类到同步模式。
public class GuardedObjectDemo {public static void main(String[] args) {GuardedObject guardedObject = new GuardedObject();new Thread(() -> {System.out.println("等待结果");Object o = guardedObject.get();System.out.println("response="+o);}, "t1").start();new Thread(() -> {System.out.println("执行任务");try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}String res = "执行结果为true";guardedObject.complete(res);}, "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();}}}
以上方法GuardedObject的get方法存在问题:
1.如果线程t2执行的时间很长,那么线程t1就会一直等待结果。
解决办法:
1.给等待线程t1设置超时时间。
设置超时时间后注意问题:
1.可能会发生虚假唤醒的时候,reponse还是为null,满足条件继续进入下一次等待,如果等待时间不减去上次已经经历的时间,等待时间就会比实际设置的timeout的时间要长。
2.超时时间要减去上次经历的时间。
public class GuardedObjectDemo {public static void main(String[] args) {GuardedObject guardedObject = new GuardedObject();new Thread(() -> {System.out.println("等待结果");Object o = guardedObject.get(5000);System.out.println("response="+o);}, "t1").start();new Thread(() -> {System.out.println("执行任务");try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}String res = "执行结果为true";guardedObject.complete(res);}).start();}}class GuardedObject {private Object response;// 获取结果public Object get(long timeout) {synchronized (this) {long begin = System.currentTimeMillis();// 经历的时间long passedTime = 0;while(response == null) {// 此次循环应该等待时间long waitTime = timeout - passedTime;// 经历的时间超过了最大等待时间if(waitTime <= 0) {System.out.println("等待超时...");break;}try {this.wait(waitTime);} catch (InterruptedException e) {e.printStackTrace();}passedTime = System.currentTimeMillis() - begin;}return response;}}// 产生结果public void complete(Object response) {synchronized (this) {this.response = response;this.notifyAll();}}}