wait和notify

关于Volatile和内存可见性的补充
网上的资料:线程修改一个变量,会把这个变量先从主内存读取到工作内存,然后修改工作内存的值,再写回主内存。
内存可见性:t1频繁读取主内存,效率比较低,就被优化成直接读自己的工作内存。
t2修改了主内存的结果,由于t1没有读主内存,导致修改不能被识别。
工作内存=》cpu寄存器
主内存=〉内存

线程的调度是无序的,但是有些场景,希望线程有序执行
join算是一种但是功能有限
wait:就是让某个线程先暂停等一等
notify:就是让该线程唤醒,继续执行

Wait

wait:发现条件不满足时/时机不成熟,就先阻塞等待。
主要做三件事:
wait必须写到synchronized代码块里面。
1.解锁
2.阻塞等待
3.当收到通知,就唤醒,同时尝试重新获取锁
notify:其他线程构造了一个成熟的条件,就可以唤醒。
wait和notify是Object的方法
notify:进行通知

public static void main(String[] args) throws InterruptedException {
            Object object=new Object();
        Thread t1=new Thread(()->{
            System.out.println("执行前");
            synchronized (object){
                try {
                    object.wait();
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
            }
            System.out.println("执行后");
        });
        t1.start();
        Thread.sleep(1000);
        Thread t2=new Thread(()->{
           synchronized (object){
               System.out.println("开始");
               object.notify();
               System.out.println("结束");
           }
        });

        t2.start();
    }

在这里插入图片描述
必须先执行wait,然后notify,才有效果!
如果现在还没有wait,就notify,相当于一炮打空了!
此时wait无法唤醒,代码不会出其他异常

使用wait,阻塞等待会让线程进入WAITING状态,wait也提供了一个带参数的版本,参数指定是最大等待时间,wait的初心就是进入阻塞的方式。

wait还有有参版本, 当使用有参版本是时,obj.wait(1000)(1秒后还不被唤醒,则强制唤醒)

notifyAll

可以有多个线程,等待同一个对象,比如t1,t2,t3中都调用object.wait,此时main中调用了object.notify(会随机唤醒一个),notifyAll(上述三个唤醒全部),此时这三个线程重新竞争锁然后依次执行。

wait和sleep的对比

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值