当前位置: 首页 > news >正文

多线程 (六) wait和notify

🎉🎉🎉点进来你就是我的人了
博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!

人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习!

欢迎志同道合的朋友一起加油喔🦾🦾🦾
目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个🐒嘿嘿
谢谢你这么帅气美丽还给我点赞!比个心


目录

一,概念: 

1)用处:

2)wait方法

3)notify 方法

二.标准代码示例

1.代码实现内容流程描述:

2.代码实现:

三. wait()和sleep()的区别



一,概念: 

1)用处:

        线程等待wait()和通知notify(),主要用于多线程之间的通信协作,而且这两个方法都是属于Object类,说明任何对象都可以调用这两个方法。

        当在一个实例对象上调用了wait()方法之后,当前线程就会在这个对象上等待。直到另外的线程调用了该对象的notify()方法,处于等待状态的线程才得以继续进行。

        这样,多线程之间就可以用这两个方法进行通信协作了。

下面引入一张图加深理解

2)wait方法

wait() 方法是 Object 类的一个方法,因此 Java 中所有的类都默认继承了该方法,因此都能使用该方法。

        但是这个wait() 方法其实是一个 final 方法,所以不可以被子类重写,子类只能使用 Object 的实现。

        wait() 方法在调用时当前线程必须要先获得该 wait() 方法所在对象的监视器锁,如果没有获取对象的监视器锁,直接调用 wait() 方法会抛出 IllegalMonitorStateException 异常。

        而所谓的获取对象的监视器锁,说白了就是共享对象的控制权

        当在一个实例对象上调用了wait()方法之后,当前线程就会释放掉它获取到的锁资源,将锁资源让给其他线程去竞争,然后当前线程会被阻塞挂起,进入等待状态,此时线程的状态为 WAITING 状态;

        只有当有其他线程调用该共享对象的 notify() 方法或者 notifyAll() 方法时,当前被阻塞挂起的线程就可能会被唤醒,然后进入就绪状态,重新再去竞争锁资源

3)notify 方法

 notify() 方法也是一个 Object 类的方法,所有 Java 类也都默认继承了该方法,都可以调用该方法,这个方法也是被 final 修饰的,因此也不可被子类重写,子类只能使用 Object 的实现。

        notify() 方法和 wait() 方法类似,都是需要先获取当前线程的共享对象监视器,如果没有也会抛出 IllegalMonitorStateException 异常。

        notify 会随机的唤醒被阻塞到该共享对象上的一个线程,而 notifyAll() 则会唤醒所有在该共享对象上被wait 方法阻塞而陷入等待状态的线程。

注意:

  1. 调用wait()notify()方法时,当前线程必须要成功获得锁(必须写在同步代码块锁中),否则将抛出异常。
  2. 只对当前单个共享变量生效,多个共享变量需要多次调用wait()方法。
  3. 如果线程A调用wait()方法后处于堵塞状态时,其他线程中断(在其他线程调用A.interrupt()方法)A线程,则会抛出InterruptExcption异常而返回并终止。

理论内容就这些,下面将上述内容用实例展示给大家,并一步一步带着大家分析和实现这两个方法,多线程中这两个方法会让程序跳跃执行,所以一定要搞清楚代码的执行流程。

二.标准代码示例

1.代码实现内容流程描述:

  1. 创建两个线程t1t2
  2. Thread0执行wait()方法。
  3. 此时Thread1得到锁,再让Thread1执行notify()方法释放锁。
  4. 此时Thread0得到锁,Thread0会自动从wait()方法之后的代码,继续执行。

通过上述流程,我们就可以清楚的看到,wait()notify()各自是怎么工作的了,也可以知道两者是怎么配合的了。

2.代码实现:

public class ThreadDemo4 {public static void main(String[] args) throws InterruptedException {Object o =new Object();Thread Thread0 =new Thread(() -> {synchronized (o) {System.out.println("wait方法开始");try {// 共享对象调用wait方法,会让该线程释放锁o.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("wait方法结束");}});Thread0.start();//此处睡眠1秒保证线程Thread0先执行Thread.sleep(1000);Thread Thread1 =new Thread(() -> {synchronized (o) {System.out.println("notify方法开始");//线程共享对象通过调用notify()方法,释放锁并通知其他线程可以得到锁o.notify();System.out.println("notify方法结束");}});Thread1.start();}
}

 从执行的结果中,要明白线程的执行顺序:

  1. Thread0调用了wait()方法后,会释放掉对象锁并暂停执行后续代码,即从wait()方法之后到run()方法结束的代码,都将立即暂停执行,这就是wait()方法在线程中的作用。
  2. CPU会将对象锁分配给一直等候的Thread1线程,Thread1执行了notify()方法后,会通知其他正在等待线程(Thread0)得到锁,但会继续执行完自己锁内的代码之后,才会交出锁的控制权。
  3. 因为本例只有两个线程,所以系统会在Thread1交出对象锁控制权后(Synchronized代码块中代码全部执行完后),把锁的控制权给Thread0(若还有其他线程,谁得到锁是随机的,完全看CPU心情),Thread0会接着wait()之后的代码,继续执行到Synchronized代码块结束,将对象锁的控制权交还给CPU。

三. wait()和sleep()的区别

1、相同点
sleep()和wait()都可以暂停线程的执行。
2、不同点
所在类不同
sleep()是Thread类的静态方法。
wait()是Object类的方法。

锁释放不同
sleep()是不释放锁的。
wait()是释放锁的。

用途不同
sleep()常用于一定时间内暂停线程执行。
wait()常用于线程间交互和通信。

用法不同
sleep()方法睡眠指定时间之后,线程会自动苏醒。
wait()方法被调用后,可以通过notify()或notifyAll()来唤醒wait的线程。

http://www.lryc.cn/news/41831.html

相关文章:

  • React--》状态管理工具—Mobx的讲解与使用
  • 有效的括号长按键入验证外星语词典字符的最短距离用栈实现队列
  • 《前端开发者的进阶之路》
  • 为什么说网络安全是风口行业?是IT行业最后的红利?
  • 使用shell 脚本,批量解压一批zip文件,解压后的文件放在以原zip文件名前10个字符的文件夹中的例子
  • 01 | Msyql系统架构
  • Linux命令---设备管理
  • 前端入门:HTML5+CSS3+JAAVASCRIPT
  • 【头歌实验】课外作业一:开通ECS及使用Linux命令
  • CMSIS-RTOS2 RTX5移植到GD32L233
  • [网络原理] 网络中的基本概念
  • BeanPostProcessor原理分析
  • 人工智能和网络安全,应该如何选择?
  • Flink预加载分区维表,实时更新配置信息
  • 大数据现在找工作难么
  • 【Linux】学会这些基本指令来上手Linux吧
  • 【沐风老师】3DMAX交通流插件TrafficFlow使用方法详解
  • c#实现视频的批量剪辑
  • 小白怎么系统的自学计算机科学和黑客技术?
  • scheduler 的使用实验对比和总结(PyTorch)
  • vue2 虚拟列表(优化版)
  • 从应用层到MCU,看Windows处理键盘输入 [1.在应用层调试Notepad.exe (按键消费者)]
  • 什么是大数据?大数据能做什么
  • Git 和 GitHub 超入门指南(四)
  • Java 响应式编程 Reactor 框架
  • Hazel引擎学习(十一)
  • 深度学习(22):如何判断训练过程中深度学习模型损失值不再下降
  • 一个比较全面的C#公共帮助类
  • 人脸识别经典网络-MTCNN(含Python源码实现)
  • OpenCV入门(十八)快速学会OpenCV 17 直线检测