[Java基础]wait(),sleep(),notify(),notifyAll()

目录

一、wait()和sleep()的区别

二、 wait(),notify()和notifyAll()

三、使用wait()方法需要满足充要条件

四、在分布式系统设计中的应用

五、另外


        在实际的工作当中,经常会用到wait(),sleep(),notify(),notifyAll()等方法,我在这里系统的整理下。

一、wait()和sleep()的区别

1. wait()是Object类的方法,而sleep()是Thread类的静态方法。wait()使线程释放对象的锁定,sleep()不会释放锁定。
2. wait()需要在同步块或者同步方法中调用,sleep()可以在任何地方调用。
3. wait()会完全释放CPU资源,sleep()没有完全释放CPU资源。
4. wait()需要捕获InterruptedException异常,而sleep()不需要捕获异常。
5. wait()被唤醒后需要获得对象锁才能继续执行,sleep()完成后自动继续执行。
6. wait()可以通过notify()/notifyAll()唤醒,sleep()通过正常超时唤醒。
7. wait()释放的锁可以通过notify()/notifyAll()直接唤醒线程获得,sleep()释放的锁需要重新竞争。
      wait()会释放对象锁,sleep()不会释放锁; wait()需处理InterruptException异常,sleep()不需要; wait()需要获得锁后才能继续执行,sleep()自动执行。

二、 wait(),notify()和notifyAll()

1. wait()方法会让当前线程释放对象的锁,并进入等待状态。应该在同步块或者同步方法中使用wait()方法。
2. notify()会随机唤醒一个等待在该对象上的线程,将其从等待池移到锁池,等待获取对象的锁。
3. notifyAll()会唤醒所有等待在该对象上的线程。
4. 唤醒线程从wait()方法返回后,并不意味着立刻获得锁,需进入锁池等待获取锁。
5. 只有拥有该对象锁的线程才能调用notify()或notifyAll()。
6. 调用wait()方法后需要在while循环中重新判断条件,而不是if,这是为处理假唤醒。
        wait()和notify()/notifyAll()主要用于线程间通信,允许线程在合适的时机释放锁并进入等待,在满足条件时通过notify唤醒继续执行。它们需要在同步代码块中配合使用,以保证数据的一致性。

三、使用wait()方法需要满足充要条件

1. 在同步块或同步方法中调用wait()方法。
这个条件是必须的,因为wait()需要先获取对象的锁,然后释放锁进入等待状态。只有在同步块或同步方法中才能获取对象锁。
2. 当前线程必须拥有该对象的监视器锁。
调用wait()方法的线程必须先获取该对象的锁,也就是说必须在同步块或同步方法中。
3. 调用wait()前保存需要通知的条件。
调用wait()进入等待前应先设置好条件,后续通过notify()/notifyAll()来通知条件已经达成。
4. 调用wait()在循环中进行等待判断。
不要用if进行判断,因为需要处理假唤醒问题,使用while循环判断条件是否满足。
5. 调用对应对象的notify()或notifyAll()方法唤醒线程。
唤醒线程后还需要获取对象锁,线程从wait()返回不意味着立即获得锁。
6. 唤醒后判断条件是否满足,满足则继续执行。
从wait()返回后要在循环中判断条件是否满足,如果不满足则继续wait()等待。
7. 释放对象锁。
wait()的线程执行完逻辑后需要释放锁,让等待的线程获取锁。
        要正确使用wait()与notify()/notifyAll(),必须要获取对象锁、判断条件、释放锁,这样可以保证数据一致性并避免死锁等问题。

四、在分布式系统设计中的应用

1. 生产者-消费者模式:wait等待数据产出,notify通知消费。
2. 阻塞队列:入队时如果队列满则wait,出队时如果队列空则wait,notify来唤醒线程。
3. 分布式锁:实现公平锁时,请求锁失败的线程可以wait,释放锁的线程notify,唤醒等待的线程。
4. 条件变量:线程在条件不满足时wait,其他线程满足条件后notify,类似监视器模式。
5. 分布式协调:一个线程等待其他线程完成某个条件后再继续,使用wait和notify可实现分布式调度。
6. 异步处理结果:一个线程等待另一个线程的处理结果,使用wait和notify实现异步处理。
7. 状态变更通知:一个线程完成状态变更后,通知其他关心该状态变更的线程。
        wait和notify在分布式软件设计中用途广泛,可以用于线程间通信、状态同步、数据传递等场景,实现高效且正确的多线程协调。但需要正确使用以避免死锁或其他问题。

五、另外

        notify只会随机唤醒一个等待线程,notifyAll会唤醒所有等待线程,使用要根据实际需要选择。如果调用了notify()但没有线程在等待,则notify()调用就会失效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小王师傅66

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

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

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

打赏作者

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

抵扣说明:

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

余额充值