总结多线程中wait,notify的使用

   首先wait和notify都是属于Object类中的方法,所以在使用的时候new一个类对象都是可以使用的(不能是基本数据类型)。

多个线程之间的调度是无序的,随机的,但是有些场景下我们还是需要线程之间的执行顺序是有序的,之间总结过join方法的使用,join方法是一个办法,可以让线程和线程之间是完整的串行执行的,但是功能有限。

比如现在有t1和t2两个线程,t1的代码逻辑执行到一半的时候,此时我需要让t1线程停下来去执行t2线程,此时join方法是做不到的。但是wait是可以做到的。

在t1线程中调用wait方法,就会让这个线程进行阻塞状态,暂时不参与CPU的调度执行,此时t2线程就可以执行了,那t2线程的逻辑执行完了,需要让t1这个线程再继续执行,就需要通知t1线程,用notify方法,告诉t1线程,此时你可以继续执行了。notify就是把这个线程唤醒。

  所以wait:当发现条件不满时、时机不成熟时,先进行阻塞等待状态

          notify:其他的线程有这个成熟的条件了,再通知wait的线程继续执行。

此时就更可以灵活的控制线程的顺序,让线程之间有序的执行。

使用wait方法要注意:此时在某一个线程中调用wait方法时,wait干了3件事:

  1.释放锁     2.进入阻塞状态等待      3.等收到notify通知的时候,就唤醒,然后尝试重新获取锁

所以在使用wait方法时要和synchronized(监视器锁)搭配使用,也就是在wait的逻辑要写在synchronized中,(先要获取一个锁才能进行释放锁操作)。而且wait和notify方法的执行也是有顺序的,wait方法要先执行完成能之后才能执行notify方法,也就是说notify方法也要写在锁代码块中,并且和wait方法同时竞争一个锁对象,等wait释放锁之后,才可以通知。如果没有wait,就notify,此时也不会有副作用,但是我们想要的功能就实现不了了。

可以参考下面代码:

/*wait主要做三件事:1.解锁  2.阻塞等待  3.当收到通知时就唤醒同时尝试重新获取锁
*  所以wait必须要写到synchronized代码块里面(因为只有先加锁才能解锁)*/
public class ThreadDemo18 {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("notify之前:");
        Object locker = new Object();
        Thread t1 = new Thread(() -> {
            try {
                System.out.println("wait开始 ");
                synchronized (locker) {
                    locker.wait();
                }
                System.out.println("wait结束 ");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();

        Thread.sleep(1000);
        Thread t2 = new Thread(() -> {
            synchronized (locker) {
                locker.notify();
            }
        });
        t2.start();
        System.out.println("notify之后 ");
    }
}

此时要区分wait notify和join的区别:

      join方法是让两个线程完整的执行串行,有t1和t2两个线程,要等t1线程完全执行完了才让t2线程继续执行,而wait notify方法是让t1线程执行一部分,然后让t2线程开始执行,然后再让t1线程继续执行,再让t2线程执行.........

还有一个唤醒操作,是notifyAll方法,这个方法是和notify方法并列的存在的,比如此时有一个场景是有多个线程都等待一个线程,t1,t2,t3线程都调用wait方法,(并且都进入waiting状态)如果此时在main线程中去调用notify方法,就会随机唤醒一个123其中的一个线程。(另外两个线程仍然是waiting状态(调用wait方法会出现 waiting状态))

notifyAll方法则会同时唤醒三个线程,让这3个线程同时去获取一个锁对象,然后一次执行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

良月初十♧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值