返回顶部
首页 > 资讯 > 后端开发 > JAVA >wait 和 notify
  • 259
分享到

wait 和 notify

java面试java-ee 2023-09-21 20:09:15 259人浏览 八月长安
摘要

✨个人主页:bit me👇 ✨当前专栏:Java EE初阶👇 ✨每日一语:阅己,越己,悦己;自行,自省,自醒;无味,无谓,无畏。 目 录

请添加图片描述

✨个人主页:bit me👇
✨当前专栏:Java EE初阶👇
✨每日一语:阅己,越己,悦己;自行,自省,自醒;无味,无谓,无畏。

目 录

⏰一. wait 和 notify 的引入

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

wait 和 notify 相比于 join 能更好的控制线程之间的执行顺序

  • wait (等待):让当前线程进入等待状态
  • notify (通知/唤醒):唤醒对应的 wait 线程。(从阻塞状态唤醒到就绪状态)

注意: wait, notify都是 Object 类的方法.

  • 使用 o1.notify() 就可以唤醒调用 o1.wait 的线程!!
  • 使用 o2.notify() 是不可以唤醒调用 o1.wait 的线程!

 

⏲二. wait()方法和notify()方法

对于 wait 来说,内部的执行过程还有点小麻烦

  1. 释放

wait 一上来就得释放锁,,得在调用 wait 之前,先拿到锁,wait 必须要放到 synchronized 中使用,synchronized 加锁的对象必须是和调用 wait 方法的对象是同一个对象,还得和调用 notify 的对象是同一个对象!!!

  1. 等待通知

  2. 当通知到达之后,就会被唤醒,并且尝试重新获取锁

wait 结束等待的条件:

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

代码示例: 观察wait()方法使用

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

在这里插入图片描述

notify 方法是唤醒等待的线程

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

举例实现 wait 和 notify 的内部执行过程:创建两个线程 一个线程调用 wait,一个线程调用 notify

public class Demo18 {//这个对象用来做锁对象public static Object locker = new Object();public static void main(String[] args) {    //用来取等待    Thread waitTask = new Thread(()->{        synchronized (locker) {            try {                System.out.println("wait 开始");                locker.wait();                System.out.println("wait 结束");            } catch (InterruptedException e) {                e.printStackTrace();            }        }    });    waitTask.start();    //创建一个用来通知 / 唤醒的线程    Thread notifyTask = new Thread(()->{       //让用户来控制,用户输入某个内容之后,再执行通知        Scanner scanner = new Scanner(System.in);        System.out.println("输入任意内容,开始通知:");        //next 会阻塞,直到用户真正输入内容以后        scanner.next();        synchronized (locker){            System.out.println("notify 开始");            locker.notify();            System.out.println("notify 结束");        }    });    notifyTask.start();}}

执行过程及结果:

在这里插入图片描述

线程 1 需要先计算一个结果,线程 2 来使用这个结果,线程 2 就可以 wait ,线程 1 计算完结果之后,notify ,唤醒线程 2。

  • wait 和 notify 机制,还能有效避免 "线程饿死"。(有些情况下,调度器可能分配不均匀,导致有些线程反复占用 CPU,有些线程始终捞不着 CPU)

例如:

多个线程抢占一个锁,一个线程 A 抢到了,其他线程排队等待,但是抢到锁的线程 A 却无法完成任务,占着锁不放,导致其他锁也不能干活儿,于是这个线程 A 决定释放锁出来,在外面等待,给其他的锁一些机会,由于线程之间在系统里的调度是随机的,可能下次又是线程 A 进来了,于是多次情况下都是线程 A 占用了 CPU,其他线程都碰不到,导致线程饿死,旱的旱死,涝的涝死。

因此使用 wait 和 notify 就可以解决上述问题,让后面的多个线程拿到锁之后判定当前任务是否可以执行,如果能就干活,不能就进行 wait !wait 来等待合适的时候(条件满足)再继续执行 / 再参与竞争锁

拓展:

  • 线程进入了 WAITING 状态,则务必要其他线程来主动唤醒
  • 线程进入了 BLOCKED 状态,这个则是其他线程把锁释放之后,操作系统来负责唤醒
  • 线程进入了 TIMED_WAITING 状态,操作系统会计时,时间到了之后进行唤醒

这三个阻塞的状态,都会导致 PCB 进入内核队列中对应的阻塞队列。操作系统内核是不区分这三个的状态的!这三个状态是 JVM 中的状态,操作系统内核中衡量线程的状态是另外的方式,没有 JVM 里面的这么细。

notify方法只是一次唤醒某一个等待线程. 使用notifyAll方法可以一次唤醒所有的等待线程.

 

⏱三. wait 和 sleep 的对比(面试题

其实理论上 wait 和 sleep 完全是没有可比性的,因为一个是用于线程之间的通信的,一个是让线程阻塞一段时间,唯一的相同点就是都可以让线程放弃执行一段时间

他们俩都会让线程进入阻塞,阻塞的原因和目的不同,进入的状态也不同,被唤醒的条件也不一样。

实际开发中会很少使用 sleep ,目的是为了 “放权” ,暂时让出当前 CPU 的使用权。之所以 sleep 使用的少,等待的时间太固定了,要是有突发情况想提前唤醒并不是那么容易,wait 就用的比较多了,wait 可以进行死等,也能设置最长等待时间(涵盖了 sleep 的功能)

1. wait 需要搭配 synchronized 使用. sleep 不需要.
2. wait 是 Object 的方法 sleep 是 Thread 的静态方法.

来源地址:https://blog.csdn.net/m0_67660672/article/details/129505822

--结束END--

本文标题: wait 和 notify

本文链接: https://lsjlt.com/news/414574.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • wait 和 notify
    ✨个人主页:bit me👇 ✨当前专栏:Java EE初阶👇 ✨每日一语:阅己,越己,悦己;自行,自省,自醒;无味,无谓,无畏。 目 录 ...
    99+
    2023-09-21
    java 面试 java-ee
  • 为什么不用Wait和Notify
    这篇文章主要介绍“为什么不用Wait和Notify”,在日常操作中,相信很多人在为什么不用Wait和Notify问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”为什么不用Wai...
    99+
    2024-04-02
  • JavaEE中volatile、wait和notify详解
    目录一.volatile 关键字. 1.volatile 能保证内存可见性问题2.volatile 不能保证原子性 二.wait和notify1.wait方法2....
    99+
    2023-02-03
    Java的volatile javaee wait notify javaee volatile
  • 聊聊Object类中的wait()和notify()方法
    目录Object类中的wait()和notify()方法一、特点二、wait()方法的作用三、notify()方法的作用四、wait()和notify()的使用object中的wai...
    99+
    2024-04-02
  • java多线程wait()和notify()如何使用
    小编给大家分享一下java多线程wait()和notify()如何使用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!注:wait()和notify()应当用在synchronized内package com.te...
    99+
    2023-06-02
  • Java多线程之死锁问题,wait和notify
    文章目录 一. synchronnized 的特性1. 互斥性2. 可重入性 二. 死锁问题1. 什么是死锁2. 死锁的四个必要条件3. 常见的死锁场景及解决3.1 不可重入造成的死锁3....
    99+
    2023-09-13
    java 死锁 wait notify synchronized
  • 怎么在Java中正确使用wait, notify和notifyAll
    这篇文章将为大家详细讲解有关怎么在Java中正确使用wait, notify和notifyAll,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。wait, notify 和 notifyAll,这些在多线程...
    99+
    2023-06-17
  • Java多线程死锁问题详解(wait和notify)
    目录一. synchronnized 的特性1. 互斥性2. 可重入性二. 死锁问题1. 什么是死锁2. 死锁的四个必要条件3. 常见的死锁场景及解决3.1 不可重入造成的死锁3.2...
    99+
    2023-01-05
    Java多线程死锁 java死锁的原因及解决方法 java多线程死锁问题
  • Java多线程wait()和notify()方法详细图解
    目录一、线程间等待与唤醒机制二、等待方法wait()三、唤醒方法notify()四、关于wait和notify内部等待问题(重要)五、完整代码(仅供测试用)总结一、线程间等待与唤醒机...
    99+
    2022-11-13
    多线程wait notify 线程的wait和notify 线程notify和wait区别
  • 为什么wait和notify必须放在synchronized中使用
    目录wait/notify基础使用wait/notify和synchronized一起用?原因分析wait和notify问题复现总结前言: 在多线程编程中,wait 方法是让当前线程...
    99+
    2024-04-02
  • 分析java并发中的wait notify notifyAll
    目录一、前言二、常见的同步场景2.1、设置一个判断的标志位2.2、线程的 join 方法2.3、使用闭锁 CountDownLatch2.4、利用 wait / notify 优化标...
    99+
    2024-04-02
  • 如何使用wait() 和notify() 机制来完成睡眠和踢
    今天就跟大家聊聊有关如何使用wait() 和notify() 机制来完成睡眠和踢,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。使用 wait() 和 notify() 机制来完成“睡...
    99+
    2023-06-03
  • Java使用wait和notify实现线程之间的通信
    目录一. 为什么需要线程通信二. wait和notify方法1. wait()方法2. notify()方法 3. notifyAll()方法三. 使用wait和notif...
    99+
    2024-04-02
  • Java 中Object的wait() notify() notifyAll()方法使用
    Java 中Object的wait() notify() notifyAll()方法使用一、前言  对于并发编程而言,除了Thread以外,对Object对象的wati和notify对象也应该深入了解其用法,虽然知识点不多。二、线程安全基本...
    99+
    2023-05-31
    java object wait()
  • 浅谈Java线程间通信之wait/notify
    Java中的wait/notify/notifyAll可用来实现线程间通信,是Object类的方法,这三个方法都是native方法,是平台相关的,常用来实现生产者/消费者模式。先来我们来看下相关定义:wait() :调用该方法的线程进入WA...
    99+
    2023-05-31
    java 线程wait notify
  • 基于线程的wait和notify使用,生产消费案例
    目录案例图解生产方逻辑图消费方逻辑图代码实现多个线程可以相互竞争,也可以互相协作完成一件事情。 Object的相关方法 Obje...
    99+
    2024-04-02
  • java并发中wait notify notifyAll的示例分析
    这篇文章主要介绍java并发中wait notify notifyAll的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、前言java 面试是否有被问到过,sleep 和 wait 方法的区别,关于这个问题...
    99+
    2023-06-15
  • Java中怎么正确使用wait-notify方法
    本篇内容介绍了“Java中怎么正确使用wait-notify方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. sleep(long n...
    99+
    2023-06-29
  • Java中怎么使用wait和notify实现线程间的通信
    这篇“Java中怎么使用wait和notify实现线程间的通信”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java中怎么使...
    99+
    2023-06-30
  • Java线程通信之wait-notify通信方式详解
    目录1.线程通信的定义2.为什么需要wait-notify3.wait方法和notify方法1、对象的wait()方法2、对象的notify()方法4.wait方法和notify方法...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作