当前位置:网站首页>wait() ,notify(),notifyAll()以及wait()与sleep()比较
wait() ,notify(),notifyAll()以及wait()与sleep()比较
2022-08-02 13:13:00 【厚积薄发ض】
目录
使用wait()和notify可以很好地进行线程间通信,减少CPU资源的浪费
什么是等待和通知?
等待通知两个操作可以很好的解决多线程之间的并发执行.比如在饭店做饭,厨师要做好饭端给服务员,然后服务员在端给客人,在厨师正在做菜的过程中服务员就在等待中,等厨师做好菜之后按下铃就通知服务员来取菜.
线程也一样,线程A要进行计算结果,而线程B要利用线程A计算的结果,此时在线程A进行计算时,线程B就在等待,等线程A计算完之后立马通知线程B.两个线程很好地进行了线程间通信.
wait方法
wait就是进行等待,从运行状态到阻塞状态(WAITING),直到该线程被通知或者中断而停止;
wait执行流程
- wait()先要释放锁
- 等待通知(也可能被中断)
- 接收到通知,重新尝试获取锁(与其他线程竞争重新获取锁)
wait注意事项
- 由于wait第一步就要先释放锁,所以wait必须要在synchronized中使用,不在synchronized中使用就会报错,同时被加锁的对象要和调用wait()的对象是同一个对象
- wait()方法是object成员方法
notify方法
notify方法使对应的wait线程唤醒,从阻塞状态变为运行状态
notify注意事项
- notify同样也要在synchronized中使用,否则报错
- notify也是object成员方法
- 当调用notify方法时只是进行通知,要等到synchronized代码块执行完毕,此时才能释放锁,对应wait的线程才能尝试获取锁
- notify只能唤醒一个对应wait的线程,如果有多个线程呈WAITING状态,随机挑选一个唤醒(具体取决于JVM的实现)
notifyAll方法
notifyAll用来唤醒多个线程,将所有呈WAITING状态的线程都进行唤醒
- notifyAll方法也是object成员方法
- notifyAll方法同样在使用时也要进行加锁,在synchronized关键字中使用
代码演示:
public static volatile Object locker = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(()->{
synchronized(locker){
System.out.println("开始等待");
try {
locker.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束等待");
}
});
t1.start();
Thread t2 = new Thread(()->{
synchronized(locker){
System.out.println("请输入一个数字开始通知");
Scanner scan = new Scanner(System.in);
scan.nextInt();
locker.notify();
System.out.println("通知结束");
}
});
t2.start();
}wait()和notify也能够有效避免"线程饿死"
什么是线程饿死???
线程饿死指的是线程反复在CPU上运行(但是并没有执行任务),这就导致其他线程没有在CPU上运行,这些线程就被称为线程饿死
而使用wait()和notify就可以很好地去避免.
我们可以让反复在CPU上执行的线程使用wait,让其没有在执行任务时先进行等待,等着他要开始执行任务时,在进行通知notify让它去CPU上进行.
wait和sleep的区别
- 从实现类看 , wait是object类成员方法,sleep是Thread类的方法
- 从唤醒方式来看 , wait方法要通过notify()方法进行通知唤醒,而sleep是等待时间到了立即被唤醒
- 从加锁来看 ,wait需要加锁要在synchronized中使用,而sleep不需要加锁
- 从释放锁不同 ,wait主动释放锁,sleep不释放锁
- 从线程状态看,wait在WAITING状态,而sleep是在TIMED_WAITING状态
边栏推荐
- UAC绕过学习-总结
- Name conventions in FreeRTOS
- 节省50%成本!京东云重磅发布新一代混合CDN产品
- 【C语言】手撕循环结构 —— while语句
- qt 编译报错 No rule to make target
- 3 ways for OpenFeign to set headers
- 【C语言】剖析函数递归(2)
- The uniapp/applet onload method executes the interpretation every time the page is opened
- 【C语言】剖析函数递归(1)
- SQL Server 2019 installation error 0 x80004005 service there is no timely response to the start or control request a detailed solution
猜你喜欢

【C语言】夏日一题 —— 求最大公约数和最小公倍数

photo-sphere-viewer Chinese documentation

工厂方法模式

k8s之KubeSphere部署有状态数据库中间件服务 mysql、redis、mongo

js true 3d histogram plugin

php - the first of three solid foundations

Mysql索引详解(图文并茂)

为什么IDEA连接mysql Unable to resolve table 编译报错但是可以运行

this的绑定指向详细解答

js semi-circle loading progress animation js special effects
随机推荐
基于华为eNSP的企业网络规划
Win11怎么修改关机界面颜色?Win11修改关机界面颜色的方法
How to turn off hardware acceleration [easy to understand]
The uniapp/applet onload method executes the interpretation every time the page is opened
GCC版本升级到指定版本
[typescript] Use the RangePicker component in antd to implement time limit the previous year (365 days) of the current time
js semi-circle loading progress animation js special effects
UAC绕过学习-总结
如何通过DBeaver 连接 TDengine?
路由-Tab切换页面
Flashback Technology of Oracle Database
汉源高科千兆12光12电管理型工业以太网交换机 12千兆光12千兆电口宽温环网交换机
Markdown怎么加入emoji
selenium chrome driver运行时的cannot determine loading status from target frame detached问题
高效代码静态测试工具Klocwork 2022.2——Portal全新升级、支持RLM
this的绑定指向详细解答
最小割和对偶图(未完成)
【C语言】剖析函数递归(3)
Introduction to Scala Basic Syntax (3) Various Operators in Scala
“二舅”火了,自媒体短视频“爆火”的基本要素,你知道吗?