java yied的用法,Java多线程的wait(),notify(),notifyAll()、sleep()和yield()方法使用详解,...

Java多线程的wait(),notify(),notifyAll()、sleep()和yield()方法使用详解,

Java多线程中的wait(),notify(),notifyAll()、sleep()和yield()方法

我们先从一个案例开始:

static public class WaitingTest {

//static创建静态对象,确保是同一个monitor对象

static Object obj = new Object();

public static void main(String[] args) {

//new Thread(Runnable target, String name)

//第一个线程,匿名内部类形式创建,name:"等待线程"

new Thread(new Runnable() {

@Override

public void run() {

while(true) {

synchronized (obj) {

System.out.println(Thread.currentThread().getName()+

"===>获取到锁对象,调用wait方法,进入waiting状态,释放锁对象");

try {

obj.wait(); //无限等待,如果想唤醒一个正在等待的线程,那么需要开启一个线程通过notify()或者notifyAll()方法去通知正在等待的线程获取monitor对象。notify()唤醒一个wait对象,或者notifyAll唤醒所有wait对象。

} catch (InterruptedException e) {

e.printStackTrace();

}

//若没有notify()唤醒,则下面这句话永远不执行

System.out.println(Thread.currentThread().getName()+

"=====>从waiting状态醒来,获得了锁对象,可以继续执行了...");

}

}

}

},"等待线程").start();

//第二个线程,同样也是匿名内部类形式创建,name:"唤醒线程"

new Thread(new Runnable() {

@Override

public void run() {

while(true) {

System.out.println(Thread.currentThread().getName()+"=====>休眠三秒钟");

try {

Thread.sleep(3000L);//虽然当前线程进入了睡眠状态,但是依然持有monitor对象。在中断完成之后,自动进入唤醒状态从而继续执行代码

} catch (InterruptedException e) {

e.printStackTrace();

}

synchronized (obj) {

System.out.println(Thread.currentThread().getName()+

"=====>获得了锁对象,调用notify方法,释放锁对象");

obj.notify();

}

}

}

},"唤醒线程").start();

}

}

执行结果:

​ 等待线程===>获取到锁对象,调用wait方法,进入waiting状态,释放锁对象

​ 唤醒线程=====>休眠三秒钟

​ 唤醒线程=====>获得了锁对象,调用notify方法,释放锁对象

​ 唤醒线程=====>休眠三秒钟

​ 等待线程=====>从waiting状态醒来,获得了锁对象,可以继续执行了...

​ 等待线程===>获取到锁对象,调用wait方法,进入waiting状态,释放锁对象

​ 唤醒线程=====>获得了锁对象,调用notify方法,释放锁对象

​ 唤醒线程=====>休眠三秒钟

​ 等待线程=====>从waiting状态醒来,获得了锁对象,可以继续执行了...

​ 等待线程===>获取到锁对象,调用wait方法,进入waiting状态,释放锁对象

5b723bf3962071726519eb602c2f91b7.png

wait()方法:

(1)调用了wait()之后当前线程会处于等待状态(无限等待状态)。

(2)每个线程必须持有该对象的monitor(Object's monitor)。如果在当前线程中调用wait()方法之后,该线程就会释放monitor的持有对象并让自己处于等待状态。

(3)如果想唤醒一个正在等待的线程,那么需要开启一个线程通过notify()或者notifyAll()方法去通知正在等待的线程获取monitor对象。当然,需要注意的一点就是,必须是同一个monitor对象。如此,该线程即可打破等待的状态继续执行代码。

notify()方法:

(1)当一个线程处于wait()状态时,也即等待它之前所持有的object's monitor被释放,通过notify()方法可以让该线程重新处于活动状态,从而去抢夺object's monitor,唤醒该线程。

(2)如果多个线程同时处于等待状态,那么调用notify()方法只能随机唤醒一个线程。

(3)在同一时间内,只有一个线程能够获得object's monitor,执行完毕之后,则再将其释放供其它线程抢占。

notifyAll()方法:

(1)notifyAll()只会唤醒那些等待抢占指定object's monitor的线程,其他线程则不会被唤醒。

(2)notifyAll()只会一个一个的唤醒,而并非统一唤醒。因为在同一时间内,只有一个线程能够持有object's monitor

(3)notifyAll()只是随机的唤醒线程,并非有序唤醒。

总结:

​ wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能。因为都个对像都有锁,锁是每个对像的基础,当然操作锁的方法也是最基础了。

1fd4a45b8853d06512aa32a65377ab2e.png

sleep()方法:sleep(long millis) sleep(long millis, int nanos)

(1)调用sleep()之后,会引起当前执行的线程进入暂时中断状态,睡眠状态,即阻塞状态。

(2)虽然当前线程进入了阻塞状态,但是依然持有monitor对象。

(3)在中断完成之后,自动进入就绪状态。sleep()方法虽然会使线程中断,但是不会将自己的monitor对象释放,在中断结束后,依然能够保持代码继续执行。

yield()方法:线程让步

(1)使线程从运行状态到就绪状态,所以yield()方法很有可能刚执行完又继续获取到CPU资源继续执行。

(2)调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程,即让系统线程调度器重新调度。

(3)它跟sleep方法类似,同样不会释放锁。但是yield不能控制具体的交出CPU的时间(没有形参)。

(4)yield()只会让同优先级或更高优先级得到执行机会,而sleep()是无限制的。

最后附一张我自己的手绘多线程生命周期图(字有点丑,请见谅)

2b6daeb9af2754ab0ae8fa2a920dc15c.png

如有错误,欢迎指点

相关文章暂无相关文章

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/485694.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu-server-18.04 设置开机启动脚本

ubuntu-16.10 开始不再使用initd管理系统,改用systemd systemd is now used for user sessions. System sessions had already been provided by systemd in previous Ubuntu releases. 快速看了 systemd 的使用方法,发现改动有点大, 包括用 …

海马体启发的记忆模型

来源:混沌巡洋舰 记忆是人类智能的关键,我们因为记忆可以把过去和当下整合成为一体, 并且可以预测未来。记忆不仅是一个信息承载的工具, 更是世界模型的本体, 它无时无刻不在刻画未来, 也被当下影响&#…

Leetcode--239. 滑动窗口最大值

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回滑动窗口中的最大值。 示例: 输入: nums [1,3,-1,-3,5,3,6,7], 和 k 3 输出: [3,3,5,5,6,7] 解释: …

java中build是什么意思,Java中的Stream.Builder build()

Stream.Builder类的build()方法将构建流,并将此构建器转换为已构建状态。语法如下-Stream build()以下是实现Stream.Builder类的build()方法的示例-示例import java.util.stream.Stream;public class Demo {public static void main(String[] args) {Stream.Builder…

设置build.gradle打包时自动加时间

在build.gradle中添加以下函数: def releaseTime() {return new Date().format("yyyyMMddHHmm", TimeZone.getTimeZone("GMT08:00")) }引用这个函数: def fileName "SecyrityPassDemo_${defaultConfig.versionName}_${release…

Leetcode--283. 移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原数组上操作,不能拷贝额外的数组。 尽量减少操作次数。 class Solution { publ…

DeepMind最新发现!神经网络的性能竟然优于神经符号模型

来源:深度学习这小事按照之前的常识,结合了算法和符号推理技术的神经符号模型(Neurosymbolic Models),会比神经网络更适合于预测和解释任务,此外,神经符号模型在反事实方面表现更好。而Neural-S…

php搜索间隔,php – 如何查找超过2个用户的匹配时间间隔

要查找user1和user2都是免费的,请尝试以下操作:selecta.datetime_start as user1start,a.datetime_end as user1end,b.datetime_start as user2start,b.datetime_end as user2end,case when a.datetime_start > b.datetime_start then a.datetime_startelse b.da…

AJAS

发送HTTP 接收服务器数据转载于:https://www.cnblogs.com/chenliuxiao/p/9288046.html

刚刚Sci-Hub和特朗普一样被永久封禁,Twitter官方:不得上诉

来源:量子位晓查 发自 凹非寺 公众号:QbitAI今天,Twitter官方宣布永久封禁特朗普的账号。而另一个账号的封禁恐怕更让科学界感到震惊。有用户发现,Sci-Hub的Twitter账号和特朗普一样,都被完全清空了。随后,…

php文件锁 阻塞区别,php文件锁阻塞模式和非阻塞模式

1、阻塞模式(如果其它进程已经加锁文件,当前进程会等其它进程解锁后继续执行)$handle fopen(‘lock.txt‘, ‘r‘);//锁定if(flock($handle,LOCK_EX)){//to do something//解锁flock($handle, LOCK_UN);}//关闭文件fclose($handle);?>2、非阻塞模式(如果其它进…

javaweb简要介绍,虚拟路径,虚拟主机

1. 静态,动态:是否随时间,地点,用户操作的改变而改变 动态网页 需要使用到 服务端脚本语言(JSP) 2. 架构: CS: Client Server eg:qq,微信,cs游戏 不足: 1.如果软…

c#之using关键字

1、using可以引入命名空间; 2、在using语句里声明的变量,使用完后会自动调用Dispose方法(实现IDisposable接口)。 using 语句允许程序员指定使用资源的对象应当何时释放资源。using 语句中使用的对象必须实现 IDisposable 接口。此…

物理学中的不确定性

来源:人机与认知实验室吴骏(香港中文大学通识教育基础课程讲师)【物理研究的只是模型,而不是真理】物理学中的确定性问题缘起于我正在教授的《与自然对话》[1] 这门课。其中节选了詹姆士华生 (James Watson) 在2003年写的一本畅销…

php链接javascript,javascript - 添加类=“行为链接”到活动页面 - PHP或JS - SO中文参考 - www.soinside.com...

我在HTML页面简单的代码&#xff1a;HomeUsersContact注&#xff1a;(在配置文件中)BASE_URL <?php define(BASE_URL, http://localhost); ?>BASE_MEMBERS <?php define(BASE_MEMBERS, BASE_URL . /members/); ?>现在&#xff0c;我需要什么&#xff1f;上课…

JSP执行流程

第一次访问&#xff1a;服务端将jsp翻译成java&#xff0c;再将Java编译成class文件 第二次访问&#xff1a;直接访问class文件较快&#xff0c;所以第一次访问比较慢&#xff0c;以后就快了 &#xff08;如果服务器代码修改了&#xff0c;则需要重新进行翻译&#xff0c;编译…

通俗易懂的来理解Iaas,Paas,SaaS

首先我们先来了解一下这几个单词的意思和完全的英文 Iaas:Infrastructure as a service 基础设施即服务 Paas:Platform as a service 平台即服务 Saas:Sofware as a service 软件基服务 怎么说&#xff0c;看这几个上面的单词是不是看的一脸懵逼了&#xff0c;不是说好了…

玩电子游戏的神经网络,告诉我们大脑是如何决策的

来源&#xff1a;混沌巡洋舰当你开车的时候&#xff0c;你的大脑会接收大量的视觉信息&#xff0c;并用它来做出驾驶的决定&#xff0c;比如什么时候刹车或者换车道。大脑需要决定在你的视野中哪些信息是做出这些决定所必需的。例如&#xff0c;另一辆车的位置是非常重要的&…

java.lang.math.trunc,java – JPA/Hibernate返回BigDecimal不长

我正在计算按月分组的SUMQuery q entityManager.createNativeQuery(qlString);q.setParameter("program", program);SuppressWarnings("unchecked")List resultList (List) q.getResultList();long tend System.currentTimeMillis();当我传入两个result…

get,post请求的编码统一

get提交方式&#xff1a;methpd"get"与地址栏&#xff0c;超链接(<href"xx">)请求方式&#xff0c;默认都属于get提交方式 http://localhost:8080/Test/front/show.jsp&#xff1f;unameadmin&upwd123&uhobbies%E8%B6%B3%E7%90%83&uhob…