考虑以下场景需求:
需要用到保护性暂停:一个线程等待另外一个线程的执行结果 这里我们让A,B同学关联到一个类。
import org.apache.log4j.Logger; public class Demo1 { private static Logger logger = Logger.getLogger(Demo1.class); public static void main(String[] args) { GuardedObject guardedObject=new GuardedObject(); new Thread(() -> { try {//模拟计算花费了2s logger.debug("A同学正在计算"); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } Message Ares = new Message();//将答案算了出来 guardedObject.computeRes(Ares); logger.debug("A同学计算完了,将答案传给了B"); }, "A同学").start(); new Thread(()->{ Message res=guardedObject.getRes(); logger.debug("B同学得到了A的答案res"); logger.debug("于是B同学将答案: "+res.get()+"写在了试卷上"); },"B同学").start(); } } class GuardedObject{ private Message res; //返回题目 public Message getRes(){ synchronized (this){ while (res==null){//B一直在等待A try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } return res; } } //计算题目 public void computeRes(Message res){ synchronized (this) { this.res = res; this.notify(); } } } class Message{//题目 String res; public String get(){ res="这个题的答案是:xxxxxxxxxxx"; return res; } }
结果
如果A同学计算的时间很长,那B同学就要等那么长吗? B同学也不傻,心想,我就等你一段时间,等不到我就不等了。
import org.apache.log4j.Logger; import sun.awt.windows.ThemeReader; public class Demo1 { private static Logger logger = Logger.getLogger(Demo1.class); public static void main(String[] args) { GuardedObject guardedObject=new GuardedObject(); new Thread(()->{ try { logger.debug("A同学正在计算"); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } Message res=new Message(); guardedObject.computeRes(res); logger.debug("A同学计算完了,将答案传给B"); },"A").start(); new Thread(()->{ Message res = null; try { res=guardedObject.getRes(2005); } catch (InterruptedException e) { e.printStackTrace(); } if(res==null) logger.debug("我不等了"); else logger.debug("B得到了A的答案,答案是"+res.get()); },"B同学").start(); } } class GuardedObject{ private Message res; //返回 public Message getRes(long timeout) throws InterruptedException { synchronized (this){ long begin=System.currentTimeMillis(); long passedTime=0; while (res==null){ if(timeout-passedTime<=0) break;//不等了,时间到了 this.wait(timeout-passedTime);//等待唤醒 passedTime=System.currentTimeMillis()-begin; } return res; } } //计算答案res public void computeRes(Message res){ synchronized (this) { this.res = res; this.notify(); } } } class Message{ String res; public String get(){ res="这个题的答案是:xxxxxxxxxxx"; return res; } }
将B的等待时间设置为小于A的计算时间, 虽然A依然把答案传给了B,但B也不能再处理了。
原文链接:https://blog.csdn.net/qq_43179428/article/details/106046978