full outer join 与full join的区别_sleep、yield、join都是干啥的? sleep与wait有啥区别?中篇[十五]...

点击上方 “ 布衣码农 ” ,免费订阅~选择“ 设为星标 ”,第一时间免费获得更新~

675ec05bf704bd3edd97948a4f4257db.png「布衣码农」用不到却又不得不学习了解的底层方法+1。Object中的wait、notify、notifyAll,可以用于线程间的通信,核心原理为借助于监视器的入口集与等待集逻辑。通过这三个方法完成线程在指定锁(监视器)上的等待与唤醒,这三个方法是以锁(监视器)为中心的通信方法 。除了他们之外,还有用于线程调度、控制的方法,他们是sleep、yield、join方法,他们也可以用于线程的协作,他们是围绕着线程的调度而来的 。

sleep方法

有两个版本的sleep方法,看得出来,核心仍旧是native方法。非native方法只是进行了参数校验,接着仍旧是调用的native方法,这个情形与wait是类似的e6fa061072ec7ca8b48ba6c1282efc36.png接下来仔细看下,native版本的sleep在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。注意:sleep不会释放锁,不会释放锁,不会释放锁!!!可以理解为他进入监视器这个房间之后,在这房间里面睡着了。与wait类似的是,sleep也是可中断方法(从方法签名可以看得出来,可能抛出InterruptedException),也就是说如果一个线程正在sleep,如果另外的线程将他中断(调用interrupt方法),将会抛出异常,并且中断状态将会擦除。所以对于sleep方法,要么自己醒来,要么被中断后也会醒来。对于sleep始终有一个超时时间的设置,所以,尽管他是在监视器内睡着了,但是并不会导致死锁,因为他终究是要醒来的。如下,线程休眠500毫秒,主线程50毫秒打印一次状态ps:sleep方法的调用结果为状态:TIMED_WAITING270f88838b5ad1ff5642e2fdd3cff40f.png借助于sleep方法,可以模拟线程的顺序执行比如下面示例,两个阶段,第二个阶段将在第一个阶段执行之后才会执行
package test1;import java.lang.Thread.State;public class T16 {public static void main(String[] args) {    //模拟执行任务的第一个阶段的执行    Thread stepOne = new Thread(() -> {    System.out.println(Thread.currentThread().getName()+" : 第一阶段任务开始执行");    try {        Thread.sleep(1000);        System.out.println(Thread.currentThread().getName()+" : 第一阶段任务执行结束");        } catch (InterruptedException e) {      }    }, "firstStage");    stepOne.start();    //模拟任务第二个阶段的执行    Thread stepTwo = new Thread(() -> {      while (!State.TERMINATED.equals(stepOne.getState())) {        try {        Thread.sleep(100);        System.out.println(Thread.currentThread().getName()+" : 我在等待第一阶段任务执行结束");        } catch (InterruptedException e) {        }      }      System.out.println(Thread.currentThread().getName()+" : 第二阶段任务执行结束");    }, "secondStage");    stepTwo.start();    }}
e12cf883bd0fa53fd30483d57dd70093.png另外,你应该已经注意到sleep方法都有static修饰,既然是静态方法,在Thread中的惯例就是针对于:当前线程,当前线程,当前线程!

yield方法

对于sleep或者wait方法,他们都将进入特定的状态,伴随着状态的切换,也就意味着等待某些条件的发生,才能够继续,比如条件满足,或者到时间等。但是yield方法不涉及这些事情,他针对的是时间片的划分与调度,所以对开发者来说只是临时让一下,让一下他又不会死,就只是再等等yield方法将会暂停当前正在执行的线程对象,并执行其他线程,他始终都是RUNNABLE状态e45dd78bec964a6fe84bfd4bdd059625.png不过要注意,可以认为yield只是一种建议性的,如果调用了yield方法,对CPU时间片的分配进行了“礼让”,他仍旧有可能继续获得时间片,并且继续执行。所以一次调用yield 并不一定会代表肯定会发生什么。739f021fb75fffca91583c5a85ad8435.png借助于while循环以及yield方法,也能一定程度上达到线程排序等待的效果5536a5c039765bf415ac96c33db5f81f.pngyield也是静态方法,所以,也是针对于当前线程,当前线程,当前线程。

join方法

三个版本的join方法b876f0fdec716d56a449751321c7abc1.png方法的实现过程,与wait也是非常类似,下面两个版本的方法一个调用join(0),一个参数校验后,调用join(millis),所以根本还是单参数版本的join方法7f983955a5615e56773e5f497532d6e9.png在方法深入介绍前先看个例子一个线程,循环5次,每次sleep 1s,主线程中打印信息从结果可以看到,主线程总是在线程执行之后,才会执行。也就是主线程在等待我们创建的这个线程结束,结束了之后才会继续进行2a45366aa7fe8c3c6b6ae336f5be80a1.png441e2edfdd44046f348a274c637a1963.png如果调整下顺序--->start 与 join的先后顺序,再次看下情况,可以发现顺序没有保障了19e08d88c3b4f96cd64ab1c9f7096941.png结论:主线程main中调用启动线程(调用start),然后调用该线程的join方法,可以达到主线程等待工作线程运行结束才执行的效果,并且join要在start调用后如何做到的?8c1eebce7f30b3dbfb6b3ed45e31f3c3.png从上面源代码可以看得出来,内部调用了wait方法,所以也能明白为啥join也会抛出InterruptedException了吧主线程main中调用thread.join()方法,join方法相当于join(0),也就是
  while (isAlive()) {      wait(0);  }
而这个wait(0)就相当于是this.wait(0),this就是我们自己创建的那个线程thread,看看方法的签名是不是有一个synchronized。isAlive()也是this.isAlive(),也就是如果当前线程alive(已经启动,但是未终止),那么将持续等待,等待的临界资源就是我们创建的这个线程对象本身。所以这两行代码的含义就是:该线程是否还存活?如果存活,调用join的那个线程将会在这个对象上进行等待(进入该线程对象的等待集)也就是说调用一个线程的join方法,就是在这个线程是等待,这个线程对象就是我们的锁对象(不要疑惑,Object都可以作为锁,Thread实例对象怎么不可以?)肯定大家很奇怪,既然是等待,wait又不会自己醒来,那不是出问题了吗?其实线程结束后,会调用this.notifyAll,所以主线程main会被唤醒如果传递的参数不为0,将会走到下面的分支,会wait指定时长,与上面的逻辑一致,只不过是有指定超时时长而已
  long delay = millis - now;  if (delay <= 0) {      break;  }  wait(delay);  now = System.currentTimeMillis() - base;
手动版本的等待结束只是将join方法换成了同步代码块,锁对象为那个线程的实例对象thread,调用他的wait方法从结果上看,效果一样(不过此处没有持续监测isAlive(),所以一旦主线程醒来,即使线程没有结束,也会继续,不能百分百确保main肯定等待线程结束)1e0219cfe663714a7987feff60b4aaef.png不过要注意:注释中有说明,自己不要使用Thread类的实例对象作为锁对象,如果是现在这种场景,使用join即可为什么?从目前来看,join方法就是以这个对象为锁,如果你自己在使用,又是wait又是notify(notifyAll)的,万一出现什么隐匿的问题咋办?46852b2ac2601a70a4eaa128e7fbff0a.png所以join方法的原理就是:将指定的Thread实例对象作为锁对象,在其上进行同步,只要那个线程还活着,那么就会持续等待(或者有限时长)。线程终止之后会调用自身this.notifyAll,以通知在其上等待的线程。简单说,只要他活着大家就都等着, 他死了会通知,所以效果就是在哪里调用了谁的join,哪里就要等待这个线程结束,才能继续。为什么要在start之后?f1851569f68b806a62ebe201994b6764.png如上面所示,将join改造成同步代码块如下所示,如果这段同步代码在start方法之前看下结果,没有等待指定线程结束,main主线程就结束了2256602657d7c9b0b89d184d7dd1aaec.png因为如果还没有调用start方法,那么isAlive是false(已开始未结束),主线程根本就不会等待,所以继续执行,然后继续到下面的start,然后主线程结束。所以,为什么join方法一定要在start之前?就是因为这个isAlive方法的校验,你没有start,isAlive就是false,就不会同步等待,所以必须要先start,然后才能join小结:对于join方法,有两个关键:
  • 调用的哪个对象的join?

  • 在哪里调用的?

换一个说法:join的效果是:一个线程等待另一个线程(直到结束或者持续一段时间)才执行,那么谁等待谁?在哪个线程调用,哪个线程就会等待;调用的哪个Thread对象,就会等待哪个线程结束;

状态图回顾

在回顾下之前状态一文中的切换图,又了解了这几个方法后,应该对状态切换有了更全面的认识bf491f6e4b0234de804ddc503b591b37.png

总结

对于yield方法,比较容易理解,只是简单地对于CPU时间片的“礼让”,除非循环yield,否则一次yield,可能下次该线程仍旧可能会抢占到CPU时间片,可能方法调用和不调用没差别。sleep是静态方法,针对当前线程,进入休眠状态,两个版本的sleep方法始终有时间参数,所以必然会在指定的时间内苏醒,他也不会释放锁,当然,sleep方法的调用不是必须在同步方法(同步代码块)内。join是实例方法,表示等待谁,是用于线程顺序的调度方法,可以做到一个线程等待另外一个线程,join有三个版本,指定超时时间或者持续等待直到目标线程执行结束,join也无需在同步方法(同步代码块)内。sleep和join都是可中断方法,被其他线程中断时,都会抛出InterruptedException异常,并且会醒来join方法底层依赖wait,我们对比下wait与sleep 
  • wait和sleep都会使线程进入阻塞状态,都是可中断方法,被中断后都会抛出异常

  • wait是Object的方法,sleep是Thread的方法

  • wait必须在同步中执行,sleep不需要(join底层依赖wait,但是不需要在同步中,因为join方法就是synchronized的)

  • wait会释放锁,sleep不会释放锁

  • wait(无超时设置的版本)会持续阻塞,必须等待唤醒,而sleep必然有超时,所以一定会自己醒来

  • wait 实例方法(Object),在对象上调用,表示在其上等待;sleep静态方法,当前线程  

··················END··················

注:非技术讲解配图均来源于网络

期待分享

如果对你有用

可以点个 「在看」 或者分享到 「 朋友圈 」 哦

04c27314b8092788957107970d2d6d20.png你「在看」吗? 4213c52ae9d04152bfcef4854ff37ab6.gif↓↓

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

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

相关文章

npu算力如何计算_异构计算神器来了,它能带来性能革命吗

前言&#xff1a;优化差有多要命&#xff1f;3A大作告诉您说到最近游戏圈子里的热门话题&#xff0c;刚刚在全平台上线的某“国产3A大作”显然绝对值得一提。一方面来说&#xff0c;靠着“抽卡化单机游戏”的设计&#xff0c;以及投入几十万元都难以实现全角色满状态的高氪金程…

画股票图csdn_这个股票今天是要弄啥?

点击上方蓝色字体&#xff0c;关注我们作者 | 四叶草编辑 | 易小投大盘点评今天市场上午走势相对弱势&#xff0c;盘中只有杀出一点点急跌的恐慌盘&#xff0c;有一些盘中的做T机会&#xff0c;但是确定性不是特别高&#xff0c;毕竟盘中的急跌相对幅度有限。下午指数随着一些概…

淮阴工学院计算机学院机房,实验室开放

计算机工程实验中心坚持每天14小时开放(7:30-21:30)&#xff0c;在完成基础和专业等实验教学任务外&#xff0c;还承担了各级各类培训及考试、计算机技能实训、工程设计与开发等任务&#xff0c;同事开展了多种形式的社会服务&#xff0c;以及对周边学校的服务。本中心每天坚持…

照片识别出错_云投诉丨四川德阳市民文明手册咋满篇乱码?回应:电脑识别问题,已全部收回...

封面新闻记者 王攀 王祥龙“这是密码吗&#xff1f;”9月23日&#xff0c;有四川德阳市民反映&#xff0c;该市发放的《德阳市民文明手册》看不懂。从市民提供的照片上看&#xff0c;手册内页上全是乱码。当前&#xff0c;德阳市正争创全国文明城市&#xff0c;有市民表示&…

好身材大姐姐学计算机惊喜用英语,英语作文:一个大大的惊喜A Big Surprise

英语作文:一个大大的惊喜A Big Surprise在日常学习、工作或生活中&#xff0c;大家一定都接触过作文吧&#xff0c;作文一定要做到主题集中&#xff0c;围绕同一主题作深入阐述&#xff0c;切忌东拉西扯&#xff0c;主题涣散甚至无主题。那么&#xff0c;怎么去写作文呢&#x…

2篇word文档比较重复率_本科论文写作重复率高的原因,毕业论文降重技巧总结!...

论文重复率的问题&#xff0c;是大学高等院校都比较关心的一点&#xff0c;大学生在论文写完以后&#xff0c;都要经过知网论文检测&#xff0c;在查看重复报告的时候&#xff0c;无法直视&#xff0c;因为论文重复率提高啦。经过几次论文降重修改还是没法降低论文重复率。那么…

如何做电脑桌面应用_CAD批量转PDF?一分钟教会你CAD如何转PDF,两种方法任你选择!...

作为从事CAD设计的我&#xff0c;已经深深的了解到了CAD设计行业的辛苦。dwg格式的文件作为CAD文件格式常见的专业格式&#xff0c;它能够很好的帮助我们保存好绘制好的CAD图纸。现在几乎在很多领域都可以见到&#xff0c;有的时候会根据需要对CAD图纸进行格式转换。很多的网友…

添加列属性_css多列属性

多列属性多列布局类似报纸或杂志中的排版方式&#xff0c;主要用以控制大篇幅文本。1、column-count : 分隔列数说明&#xff1a;属性规定元素应该被分隔的列数用于&#xff1a;除table外的非替换块级元素, table cells, inline-block元素2、column-gap &#xff1a; 设置列与列…

pyautogui typewrite_解放双手:Pyautogui帮你work

今天介绍一个很有用的python库——Pyautogui&#xff0c;它可以通过屏幕的xy坐标系统来确定目标位置&#xff0c;进而控制鼠标和键盘发送虚拟的点击和输入任务。这对于你要完成机械重复枯燥的电脑操作来说非常地方便。安装Pyautogui库很简单&#xff0c;命令窗口输入&#xff1…

win7 右键计算机 服务 设备管理器,win7系统计算机右键菜单添加设备管理器的操作方法...

今天和大家分享一下关于对win7系统计算机右键菜单添加设备管理器设置的方法&#xff0c;在使用win7系统的过程中经常不知道如何去对win7系统计算机右键菜单添加设备管理器进行设置&#xff0c;有什么好的办法去设置win7系统计算机右键菜单添加设备管理器呢&#xff1f;在这里小…

年月跨度_不畏困难,砥砺前行 ——国内最大跨度管桁架工程成功首滑

8月3日下午&#xff0c;由陕建机施(江苏)第二总部第一工程公司承建的330米大跨度管桁架工程——芜湖新兴铸管综合料场封闭工程顺利实现首跨滑移&#xff0c;创下国内最大跨度管桁架工程滑移记录。该工程包含一个管桁架主体大棚结构&#xff0c;两个东西毗屋网架附属结构以及一个…

python 定时器_python定时器apscheduler及一个django的小tips

类似于windows系统里的计划任务&#xff0c;需要按特定的时间周期&#xff0c;去调度执行一项任务。python里有apscheduler组件。分有阻塞式与非阻塞式&#xff0c;如下是阻塞式&#xff0c;就是不需要自己去写循环。from apscheduler.schedulers.background import BlockingSc…

八年级计算机教学论文,初二数学教学论文范文

初二数学教学论文范文在人类历史发展和社会生活中&#xff0c;数学发挥着不可替代的作用&#xff0c;也是学习和研究现代科学技术必不可少的基本工具。下面是小编为你带来的 初二数学教学论文范文&#xff0c;欢迎阅读。摘要&#xff1a;随着我国新课标教育改革的不断深化&…

网站能拿到其他网站的cookie_在网站推广中企业网站能发挥哪些作用?(一)

相信大家都知道&#xff0c;在如今这个互联网环境下的市场中&#xff0c;企业必须借助互联网的便利才能寻求更加长远的发展。而要做到这些&#xff0c;首先就要求企业建立自己的企业网站。企业网站如此重要&#xff0c;接下来易推网将为大家分析在网站推广中企业网站能发挥的作…

猎户座计划软件测试,四核配置跑分:猎户座4412性能强劲_平板电脑评测-中关村在线...

四核配置跑分&#xff1a;猎户座4412性能强劲硬件配置方面&#xff0c;纽曼Q10采用三星Exynos 4412猎户座处理器&#xff0c;搭载1GB DDR3内存&#xff0c;16GB存储空间(可通过TF存储卡扩展至32GB)&#xff0c;预装Android 4.0操作系统&#xff0c;内置蓝牙4.0模块&#xff0c;…

蛋糕是叫胚子还是坯子_教你做巧克力淋面蛋糕,掌握这个配比,好看又好吃,10分钟做一个...

淋面蛋糕不知道从什么时候开始非常流行&#xff0c;它唯美的流淌线条&#xff0c;以及简洁的造型受到很多人的喜爱&#xff0c;这对于没有任何裱花基础的小伙伴来说真是福音&#xff0c;过生日不用再去蛋糕店订蛋糕&#xff0c;而是亲手为家人制作更有意义的蛋糕&#xff0c;虽…

mysql begin end 用法_MySQL ------ 游标(CURSOR)(二十六)

MySQL执行检索操作会返回一组称为结果集的行&#xff0c;这组返回的行都是与SQL 语句相匹配的行&#xff08;零行或多行&#xff09;&#xff0c;但是&#xff0c;使用简单的select 语句&#xff0c;没有办法得到第一行、下一行、或前十行&#xff0c;也不存在一行地处理所有行…

treeview控件怎么折叠_拍摄的视频闪烁怎么办?一招就能搞定,电脑手机都适用...

视频拍摄/视频剪辑教程/新媒体大家好我是学拍视频剪辑的黑米老师很多剪辑师在剪辑时&#xff0c;总会收到一些视频画面闪烁的素材&#xff0c;这是因为机器观察到的色彩和人肉眼观察到的色彩不一样&#xff0c;当曝光变化比较明显时&#xff0c;机器会捕捉到一些肉眼观察不到的…

rocketmq 消息指定_进大厂必备的RocketMQ你会吗?

点击关注"故里学Java"右上角"设为星标"好文章不错过关于消息队列&#xff0c;相信大家都不陌生&#xff0c;现在的中大型项目中或多或少都有使用到消息队列&#xff0c;对于消息队列大家可能都有一定的了解&#xff0c;使用消息队列可以解决什么样的问题&a…

秦丝软件的服务器稳定吗,强烈推荐 | 最好的五款服装进销存软件排名

随着企业的发展和市场的需要&#xff0c;传统的手工记录法复杂而繁琐&#xff0c;且错误较多费时费力&#xff0c;尤其是服装行业&#xff0c;涉及的品牌众多&#xff0c;需要管理的货品数量多&#xff0c;质量参差不齐&#xff0c;经营管理越来越困难。在此&#xff0c;小编为…