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

多线程---wait和notify

文章目录

  • 使用场景
  • 使用方法
  • 原理
  • notify VS notifyAll

使用场景

我们都知道线程的调度是“随机的”,但是我们在很多时候都希望多个线程能够按照一个预期的顺序来执行。wait和notify就是用来调配线程执行顺序的。

使用方法

	public static void main(String[] args) {Object object = new Object();Thread thread1 = new Thread(() -> {while (true){synchronized (object){System.out.println("wait之前");try {object.wait();} catch (InterruptedException e) {e.printStackTrace();}//在notify唤醒之后执行System.out.println("wait之后");}}});thread1.start();Thread thread2 = new Thread(() -> {while (true){synchronized (object) {System.out.println("notify之前");object.notify();//在wait被唤醒之前执行System.out.println("notify之后");}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});thread2.start();}

解释:

  1. wait和notify得配合使用,wait用来让线程休眠,程序执行到wait就会进入阻塞状态;notify用来唤醒线程,直到另一个线程唤醒休眠的线程后,原线程才能继续往下走。
  2. 它们俩都得搭配synchronized使用,且在使用之前都必须加锁。因为它们是通过“锁竞争”来调配线程执行顺序的。
  3. 锁对象和调用wait和notify的对象要相同。相同才能识别。
  4. 先调用了notify再调用wait可能会发生死锁,一般都会让notify等待wait被调用到后再执行。因为,调用wait进入阻塞等待状态后,如果没有notify唤醒它,它就会一直阻塞产生死锁。
  5. notify单独使用不会报错,不会有异常。

原理

其实,wait操作本质上做了三件事儿:

  1. 释放当前锁
  2. 进行等待通知
  3. 别的线程调用notify被唤醒,然后尝试重新获取锁

为什么要先释放锁,再等待通知呢

  1. 调用wait的对象、调用notify的对象、锁对象,这三个对象是一个对象。只有wait先释放了锁,别的线程才有可能调用到notify来唤醒它。
  2. 在wait进入阻塞等待状态后,它就不会在执行其他操作了。如果不释放锁,别的线程还想借助这个锁对象来执行别的操作时,别的线程就拿不到锁不能执行。白白浪费了系统资源,降低了整体程序的执行效率,延长执行的时间。

在这里插入图片描述

notify VS notifyAll

notify:如果多个线程都在等待被唤醒,notify是随机唤醒一个。

notifyAll:如果多个线程都在等待被唤醒,notifyAll是全部唤醒。但是这些线程又会有“锁竞争”,重新竞争锁的过程仍然是串行的。

相关文章:

  • 【Android知识笔记】插件化专题(二)
  • 一、基础算法精讲:双指针
  • C++大数加法——最简单实现
  • Webpack 基础以及常用插件使用方法
  • 基于GPIO子系统编写LED驱动
  • ChatGPT如何应对用户提出的道德伦理困境?
  • 【开源】基于SpringBoot的车险自助理赔系统的设计和实现
  • 【实战】Kubernetes安装持久化工具NFS-StorageClass
  • 【Python机器学习】零基础掌握RandomForestRegressor集成学习
  • MATLAB中polyvalm函数用法
  • MySQL - UNION 与 UNION ALL
  • web - 前段三剑客
  • json格式存储b64编码的rgb raw数据
  • leetcode_2558 从数量最多的堆取走礼物
  • 进制转换10进制转二进制,n进制转16进制
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • [译]CSS 居中(Center)方法大合集
  • 【技术性】Search知识
  • 11111111
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • css系列之关于字体的事
  • eclipse(luna)创建web工程
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • JS+CSS实现数字滚动
  • js作用域和this的理解
  • mongo索引构建
  • Python语法速览与机器学习开发环境搭建
  • React 快速上手 - 07 前端路由 react-router
  • supervisor 永不挂掉的进程 安装以及使用
  • v-if和v-for连用出现的问题
  • XForms - 更强大的Form
  • 计算机常识 - 收藏集 - 掘金
  • 检测对象或数组
  • 今年的LC3大会没了?
  • 前端_面试
  • 前端性能优化--懒加载和预加载
  • 通信类
  • 正则表达式
  • 积累各种好的链接
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • $refs 、$nextTic、动态组件、name的使用
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (十八)三元表达式和列表解析
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (四)Android布局类型(线性布局LinearLayout)
  • (算法)求1到1亿间的质数或素数
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转载)Google Chrome调试JS
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • . NET自动找可写目录