• wait() ,notify(),notifyAll()以及wait()与sleep()比较


    目录

    什么是等待和通知?

    wait方法

    wait执行流程

    wait注意事项

    notify方法

    notify注意事项

    notifyAll方法

    wait()和notify也能够有效避免"线程饿死"

    什么是线程饿死???

    wait和sleep的区别


    使用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关键字中使用

    代码演示:

    1. public static volatile Object locker = new Object();
    2. public static void main(String[] args) {
    3. Thread t1 = new Thread(()->{
    4. synchronized(locker){
    5. System.out.println("开始等待");
    6. try {
    7. locker.wait();
    8. } catch (InterruptedException e) {
    9. e.printStackTrace();
    10. }
    11. System.out.println("结束等待");
    12. }
    13. });
    14. t1.start();
    15. Thread t2 = new Thread(()->{
    16. synchronized(locker){
    17. System.out.println("请输入一个数字开始通知");
    18. Scanner scan = new Scanner(System.in);
    19. scan.nextInt();
    20. locker.notify();
    21. System.out.println("通知结束");
    22. }
    23. });
    24. t2.start();
    25. }

    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状态
  • 相关阅读:
    java牛客笔试题练习日记 - java基础篇
    PostgreSQL-基本结构
    CSS 滚动驱动动画 view()
    【工作中用到的功能-windows篇】自用备忘
    leetcode:1013. 将数组分成和相等的三个部分
    向 lambda 传递 this的拷贝
    第二十一章 控制进程(二)
    python之*用法
    使用ChatGPT进行数据分析案例——贷款数据分析
    【Java】注解 之 定义注解
  • 原文地址:https://blog.csdn.net/m0_61210742/article/details/126096911