notify()和wait()
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11398563.html
notify() 和 wait() 主要是用来多个线程之间的协作。
它们都是Object的方法,任何对象都可以调用这两个方法。
首先设置一个多个线程共享的对象 :
//共享对象
Object shareObject = new Object();
1.wait() :导致当前线程等待,直到另一个线程调用该对象的notify()或者notifyAll()方法;
这里用代码解释一下:
class ThreadOne extends Thread{
@Override
public void run() {
synchronized (shareObject){
for (int i = 0; i < 10 ; i++){
System.out.println("A线程--->"+i);
shareObject.notify();
if (first){
first = false;
try {
shareObject.wait();
} catch (Exception e){
System.out.println(e);
}
}
}
}
}
}
这里的 shareObject.wait(); 会导致ThreadOne线程进入shareObject对象的等待队列(这个等待队列可能会有多个线程,这些线程都停止继续执行,进入等待状态),直到其他线程调用shareObject的notify()或者notifyAll()方法,ThreadOne线程就可能会被唤醒,因为该唤醒是从等待队列中随机抽取一个线程进行唤醒,不公平唤醒。
2.notify() :唤醒正在等待对象监视器的单个线程。这个在上面已经作了解释,下面用代码说明一下。
class ThreadTwo extends Thread{
@Override
public void run() {
synchronized (shareObject){
for (int i = 0; i < 10; i++){
System.out.println("B线程--->"+i);
shareObject.notify();
if (!first){
first = true;
try {
shareObject.wait();
}catch (Exception e){
System.out.println(e);
}
}
}
}
}
}
这里的 shareObject.notify();会从shareObject对象的等待队列中随机唤醒一个线程,但是目前的shareObject对象的等待队列中只有ThreadOne一个线程,所以它就被唤醒了。
过程如下图:

最后:wait和sleep区别
1️⃣ wait和sleep方法都可以让线程等待;
2️⃣ wait()方法可以被唤醒,sleep不能被唤醒。
3️⃣ wait()既会释放cpu,也会释放共享资源的锁,sleep()不会释放任何资源。
4️⃣ wait和sleep方法都可以使线程进人阻塞状态。
5️⃣ wait和sleep方法均是可中断方法,被中断后都会收到中断异常。
6️⃣ wait是Object的方法,而sleep是Thread特有的方法。
7️⃣ wait方法的执行必须在同步方法中进行,而sleep则不需要。
8️⃣ 线程在同步方法中执行sleep方法时,并不会释放monitor的锁,而wait方法则会释放monitor的锁。
9️⃣ sleep方法短暂休眠之后会主动退出阻塞,而wait方法(没有指定wait时间)则需要被其他线程中断后才能退出阻塞。
sleep:是Thread的静态方法,会使当前线程释放cpu,但不会释放锁资源,可以理解为只和cpu有关,不涉及锁资源。涉及锁资源的,是wait,join方法。
1️⃣ yield:也是Thread的静态方法,和sleep方法类似,会使当前线程释放cpu,但不会释放锁资源。和sleep不同的是,sleep必须设置时间,但是yield不能设置时间,时间值是随机的
2️⃣ join: 等待join方法执行线程先执行完毕, main方法再继续执行; 例如 main方法中有一个线程thread执行了thread.join() ; 那么当main方法执行到了thread.join()语句时,必须等待thread线程执行完毕,才能继续执行;thread必须执行了start方法才会这样,如果没有执行start方法main方法会直接执行下去.
结束
notify()和wait()的更多相关文章
- Thread Object wait() notify()基本
package com.thread.test.thread; import java.util.ArrayDeque; import java.util.Queue; import java.uti ...
- 如何在 Java 中正确使用 wait, notify 和 notifyAll(转)
wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait ...
- java多线程wait notify join
wait notify 几个注意点: wait 与 notify/notifyAll 方法必须在同步代码块中使用,即要先对调用对象加锁. 当线程执行wait()时,会把当前的锁释放,然后让出CPU,进 ...
- 【Java并发系列02】Object的wait()、notify()、notifyAll()方法使用
一.前言 对于并发编程而言,除了Thread以外,对Object对象的wati和notify对象也应该深入了解其用法,虽然知识点不多. 二.线程安全基本知识 首先应该记住以下基本点,先背下来也无妨: ...
- 【多线程】java多线程 测试例子 详解wait() sleep() notify() start() join()方法 等
java实现多线程,有两种方法: 1>实现多线程,继承Thread,资源不能共享 2>实现多线程 实现Runnable接口,可以实现资源共享 *wait()方法 在哪个线程中调用 则当前 ...
- #研发中间件介绍#异步消息可靠推送Notify
郑昀 基于朱传志的设计文档 最后更新于2014/11/11 关键词:异步消息.订阅者集群.可伸缩.Push模式.Pull模式 本文档适用人员:研发 电商系统为什么需要 NotifyServer? ...
- 线程同步以及 yield() wait()和notify()、notifyAll()
1.yield() 该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会. 2.wait()和notify().notifyAll() 这 ...
- java 多线程之wait(),notify,notifyAll(),yield()
wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能.因为都个对像都 ...
- wait、notify、sleep、interrupt对比分析
对比分析Java中的各个线程相关的wait().notify().sleep().interrupt()方法 方法简述 Thread类 sleep:暂停当前正在执行的线程:(类方法) yield:暂停 ...
- java中的wait(),notify(),notifyAll(),synchronized方法
wait(),notify(),notifyAll()三个方法不是Thread的方法,而是Object的方法.意味着所有对象都有这三个方法,因为每个对象都有锁,所以自然也都有操作锁的方法了.这三个方法 ...
随机推荐
- ssm项目使用过滤器出现4040错误
目录 问题 解决方法 (1)方法一 (2)方法二 问题 过滤器处理乱码问题 public class CharFilter implements Filter { @Override public v ...
- Storm集群安装Version1.0.1
Storm集群安装,基于版本1.0.1, 使用apache-storm-1.0.1.tar.gz安装包. 1.安装规划 角色规划 IP/机器名 安装软件 运行进程 nimbus zdh-237 sto ...
- CSS基础 装饰 元素本身隐藏和显示效果及案例
1.visibility:hidden; 2.display: none: 区别: 1.visibility:hidden 隐藏元素本身,且在网页中 占位置 2.display:none; 隐藏元素本 ...
- js 表格操作 全选和反选效果 案例
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Xshell 6 首次连接虚拟机 CentOS 7.6报错:/usr/bin/xauth: file /root/.Xauthority does not exist
使用 Xshell 6 首次连接虚拟机 CentOS 7.6 出现这样的提示: /usr/bin/xauth: file /root/.Xauthority does not exist 解决: 只需 ...
- c# - 关于位移符号 >> 和 << 的使用
1.前言 这是对二进制数据进行位移的方法 2.操作 using System; namespace ConsoleApp1.toValue { public class test1 { public ...
- Layui table 学习笔记
templet:'<div>{{createrFormat(d.accounts.name)}}</div>' function createrFormat(o){ retur ...
- Kube-OVN 1.2.0发布,携手社区成员打造高性能容器网络
Kube-OVN 1.2.0 新版本如期而至,支持 Vlan 和 OVS-DPDK 两种类型的高性能网络接口.本次发布得益于社区的壮大,感谢Intel爱尔兰开发团队与锐捷网络开发团队持续积极参与Kub ...
- Sharding Sphere的分库分表
什么是 ShardingSphere? 1.一套开源的分布式数据库中间件解决方案 2.有三个产品:Sharding-JDBC 和 Sharding-Proxy 3.定位为关系型数据库中间件,合理在分布 ...
- 【源码阅读】VictoriaMetrics中理解vm-backup中设置origin地址的用途
lib/backup/actions/backup.go: // 118 行 partsToCopy := common.PartsDifference(srcParts, dstParts) //要 ...