java线程-保护性暂停(wait,notify实现)


考虑以下场景需求:

  1. A同学计算一个结果res
  2. B同学需要等待A同学的结果res

需要用到保护性暂停:一个线程等待另外一个线程的执行结果
这里我们让A,B同学关联到一个类。


B同学一直等待A同学

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同学也不傻,心想,我就等你一段时间,等不到我就不等了。

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