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的方法.意味着所有对象都有这三个方法,因为每个对象都有锁,所以自然也都有操作锁的方法了.这三个方法 ...
随机推荐
- .net 经验总结
先做个自我介绍,我是 2015 年大四实习开始学习的 .net,如果从 2016 年毕业开始算,到目前为止已有 5 年的 web 开发相关经验了,自认为并不是技术很厉害的人,但是也有一点个人的经验,希 ...
- Elasticsearch单机安装Version7.10.1
1.说明 Elasticsearch单机安装, 基于Elasticsearch的7.10.1版本, 在Linux上安装Elasticsearch单机, 使用安装包elasticsearch-7.10. ...
- Hadoop单点安装(伪分布式)
Hadoop单点安装,基于版本2.7.1, 在一台Lunix主机上面安装Hdoop, 包括Hdfs的NameNode和DataNode, 以及Yarn的ResouceManager和NodeManag ...
- 使用 Docker 构建和运行自己的镜像
步骤 首先,从 GitHub 中克隆示例项目: git clone https://github.com/dockersamples/node-bulletin-board cd node-bulle ...
- html基础 表格的相关属性使用
1.1表格的基本标签 语法结构:<table> /*整体包裹部分,包裹多个tr */ <tr> /* 表格的每一个行,包裹td */ <td></td> ...
- windows 找不到文件gpedit.msc
前言: 最新在装一个软件的时候,需要更改本地组的一些内容,win+R输入gpedit.msc,提示找不到文件. 解决: 第一种方法:笔者电脑是window10 家庭版,试了网上新建一个txt文件,写入 ...
- Python中类的变量,一个下划线与两个下划线的区别
形似 功能 __xx 这是私有变量, 只有内部可以访问,外部不可以访问.但是也不是一定不可以访问,只要以 _类名__xx样式就可以访问 .但最好不要这样做,养成良好编程习惯 _x 这是实例 ...
- vue再页面渲染json数据时没有显示
对象点属性不能获取数据. 原因: 在创建数据对象时我使用了k,v方式:tempMap['category '] = this.category[i].label 如果在创建数据时使用的k,v方式,那么 ...
- 禁止yum update 自动更新系统内核
使用yum update更新系统软件时,禁止升级内核,可以防止产生因不兼容导致的未知错误. 设置前请先备份原设置文件yum.conf cp /etc/yum.conf /etc/yum.conf ...
- Nginx 防爬虫设置
在conf下 vi 一个文件agent_deny.conf 添加如下内容 #禁止Scrapy|curl等工具的抓取 if ($http_user_agent ~* (Scrapy|Curl|Http ...