wait 和 notify

news/2024/10/18 14:25:37/

由于线程之间是抢占式执行的,因此线程之间执行的先后顺序难以预知.
但是实际开发中有时候我们希望合理的协调多个线程之间的执行先后顺序

wait( )方法

wait 方法做的事

  • 使当前执行代码的线程进行等待,(把线程放到等待队列中)
  • 释放当前的锁
  • 满足一定条件时被唤醒,重新尝试获取这个锁

代码示例:

public class ThreadDemo19 {public static void main(String[] args) throws InterruptedException {Object object = new Object();System.out.println("等待前");object.wait();System.out.println("等待后");}
}

预计执行结果:
此代码中,由于没有进行任何的通知机制;所以,预期效果,是一直去等待

实际执行结果:

在这里插入图片描述
synchronized — 监视器锁
wait 要搭配 synchronized 来使用,脱离 synchronized 使用 wait 会直接抛出异常

wait 的工作过程:
1.释放锁 (得先有一个锁,才能释放)
2.等待通知 (这个过程可能很久)
3.当收到通知后,尝试重新获取锁,继续往下执行

修改之后的代码:

public static void main(String[] args) throws InterruptedException {Object object = new Object();synchronized (object){System.out.println("等待前");object.wait();System.out.println("等待后");}
}

此时运行程序,就会陷入阻塞,会持续多久,不好说

可以通过 jconsole 窗口来查看:

在这里插入图片描述

竞态条件问题

wait 方法,的执行过程分为三步,下面线程1 调用wait 方法
画图表示:

在这里插入图片描述
如何避免 竞态条件问题??
事实上,操作1 和 操作2 在wait 上是原子的
也就是说,只要调用 wait,1 和 2 是一气呵成的,不会先后执行~

wait 结束等待的条件

  • 其他线程调用该对象的 notify 方法
  • wait 等待时间超时 (wait 方法提供一个带有 timeout 参数的版本,来指定等待时间)
  • 其他线程调用该等待线程的 interrupted 方法,导致 wait 抛出 InterruptedException 异常

wait 和 sleep 的对比?

  • sleep方法:是Thread类的静态方法,当前线程将睡眠n毫秒,线程进入阻塞状态。当睡眠时间到了,会解除阻塞,进入可运行状态,等待CPU的到来。睡眠不释放锁(如果有的话)。
  • wait方法:是Object的方法,必须与synchronized关键字一起使用,线程进入阻塞状态,当notify或者notifyall被调用后,会解除阻塞。但是,只有重新占用互斥锁之后才会进入可运行状态。睡眠时,会释放互斥锁。
  • sleep 方法没有释放锁,而 wait 方法释放了锁 。
  • sleep 通常被用于暂停执行,wait 通常被用于线程间交互/通信
  • sleep() 方法执行完成后,线程会自动苏醒。或者可以使用 wait(long timeout)超时后线程会自动苏醒。wait() 方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的 notify() 或者 notifyAll() 方法

notify( )方法

notify 方法是唤醒等待的线程

  • 方法notify( ) 也要在同步方法或同步块中调用,该方法是用来通知那些可能等待该对象的对象锁的
    其它线程,对其发出通知notify,并使它们重新获取该对象的对象锁
  • 如果有多个线程等待,则有线程调度器随机挑选出一个呈 wait 状态的线程. (并没有 “先来后到”)
  • 在notify( ) 方法后,当前线程不会马上释放该对象锁,要等到执行notify( ) 方法的线程将程序执行
    完,也就是退出同步代码块之后才会释放对象锁

代码示例:

public class ThreadDemo20 {public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread t1 = new Thread(){@Overridepublic void run(){synchronized (locker){while (true){try {System.out.println("wait 开始");locker.wait();  // 要和 synchronized 对应的对象对应System.out.println("wait 结束");} catch (InterruptedException e) {e.printStackTrace();}}}}};t1.start();Thread t2 = new Thread(){@Overridepublic void run(){Scanner scan = new Scanner(System.in);System.out.println("输入任意一个整数, 继续执行notify() ");int num = scan.nextInt();synchronized (locker){System.out.println("notify 开始");locker.notify();  // notify 的对象和 wait 的对象要对应,才有效果System.out.println("notify 结束");}}};t2.start();}
}

在这里插入图片描述
执行结果:

在这里插入图片描述
画图分析执行过程:

在这里插入图片描述

notifyAll( )方法 (不建议使用)

notify 方法只是唤醒某一个等待线程,使用 notifyAll 方法可以一次唤醒所有的等待线程,这些线程再去竞争同一把锁

在这里插入图片描述


http://www.ppmy.cn/news/590573.html

相关文章

Welcome ! Please leave word here!

Welcome ! Please leave word here if you have any ideas or proposes.Thank you!

please tell me who you are?

GIT 中提示 please tell me who you are 如果使用git过程中出现了,please tell me who you are , 需要设置一下使用者的身份。 1.git config user.name "username" 2.git config user.email "usernameXXX.com"

notify和wait

public class ListAdd2 {private volatile static List list new ArrayList(); public void add(){list.add("bjsxt");}public int size(){return list.size();}public static void main(String[] args) {final ListAdd2 list2 new ListAdd2();// 1 实例化出来一…

【C++】STL——string类的基本介绍、string常见的使用、string类的接口说明、string类的容量操作

文章目录 1.C语言的字符串2.C标准库中的string类2.1string类2.2string类的常用接口说明2.3string类对象的容量操作 1.C语言的字符串 在C语言中,字符串被表示为字符数组。C语言中的字符串以’\0’字符(null字符或字符串结束符)结尾&#xff0c…

【reactor】响应式实现方法同一个参数多次传入,前两次传入实现分包数据合并,第三次并发传入实现多线程处理

以下是一个使用WebFlux的方法的示例,其中参数可以传入两次,第一次传入后进行一次处理,如果未满足继续执行的要求,则等待第二次传入,第二次传入时再基于第一次处理结果进行第二次处理,第二次处理完成后继续向下执行,如果第一次处理达到要求,则不等待直接向下执行。 imp…

完全零基础,如何学习渗透?

网络渗透这一行,做个脚本小子,使使工具啥的,个把月就学会了,这不难。 很多人把网络渗透简单的理解成就是搞网站,这是大错特错的! 不过这也难怪,Web安全那三招两式,最好教也最好学&…

【动态规划算法练习】day6

文章目录 一、53. 最大子数组和1.题目简介2.解题思路3.代码4.运行结果 二、918. 环形子数组的最大和1.题目简介2.解题思路3.代码4.运行结果 三、152. 乘积最大子数组1.题目简介2.解题思路3.代码4.运行结果 总结 一、53. 最大子数组和 1.题目简介 53. 最大子数组和 给你一个整…

###图像处理之就业前景####【转载】

个人觉得图像处理的就业还是不错的。首先可以把图像看成二维、三维或者更高维的信号,从这个意义上来说,图像处理是整个信号处理里面就业形势最好的,因为你不仅要掌握(一维)信号处理的基本知识,也要掌握图像…