java线程中yield(),sleep(),wait()区别详解

1、sleep()

使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据。注意该方法要捕捉异常。

例如有两个线程同时执行(没有synchronized)一个线程优先级为MAX_PRIORITY,另一个为MIN_PRIORITY,如果没有Sleep()方法,只有高优先级的线程执行完毕后,低优先级的线程才能够执行;但是高优先级的线程sleep(500)后,低优先级就有机会执行了。

总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。

2、join()

join()方法使调用该方法的线程在此之前执行完毕,也就是等待该方法的线程执行完毕后再往下继续执行。注意该方法也需要捕捉异常。

3、yield()

该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。

4、wait()和notify()、notifyAll()

这三个方法用于协调多个线程对共享数据的存取,所以必须在synchronized语句块内使用。synchronized关键字用于保护共享数据,阻止其他线程对共享数据的存取,但是这样程序的流程就很不灵活了,如何才能在当前线程还没退出synchronized数据块时让其他线程也有机会访问共享数据呢?此时就用这三个方法来灵活控制。

wait()方法使当前线程暂停执行并释放对象锁标示,让其他线程可以进入synchronized数据块,当前线程被放入对象等待池中。当调用notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。

notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。

注意 这三个方法都是java.lang.Object的方法。

二、run和start()

把需要处理的代码放到run()方法中,start()方法启动线程将自动调用run()方法,这个由java的内存机制规定的。并且run()方法必需是public访问权限,返回值类型为void。

三、关键字synchronized

该关键字用于保护共享数据,当然前提条件是要分清哪些数据是共享数据。每个对象都有一个锁标志,当一个线程访问到该对象,被Synchronized修饰的数据将被”上锁”,阻止其他线程访问。当前线程访问完这部分数据后释放锁标志,其他线程就可以访问了。

四、wait()和notify(),notifyAll()是Object类的方法,sleep()和yield()是Thread类的方法。

(1)、常用的wait方法有wait()和wait(long timeout);

void wait() 在其他线程调用此对象的 notify() 方法或者 notifyAll()方法前,导致当前线程等待。

void wait(long timeout)在其他线程调用此对象的notify() 方法 或者 notifyAll()方法,或者超过指定的时间量前,导致当前线程等待。

wait()后,线程会释放掉它所占有的”锁标志”,从而使线程所在对象中的其他shnchronized数据可被别的线程使用。

wait()h和notify()因为会对对象的”锁标志”进行操作,所以他们必需在Synchronized函数或者 synchronized block 中进行调用。如果在non-synchronized 函数或 non-synchronized block 中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。。

(2)、Thread.sleep(long millis)必须带有一个时间参数。

sleep(long)使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会被执行;

sleep(long)可使优先级低的线程得到执行的机会,当然也可以让同优先级的线程有执行的机会;

sleep(long)是不会释放锁标志的。

(3)、yield()没有参数

sleep 方法使当前运行中的线程睡眠一段时间,进入不可以运行状态,这段时间的长短是由程序设定的,yield方法使当前线程让出CPU占有权,但让出的时间是不可设定的。

yield()也不会释放锁标志。

实际上,yield()方法对应了如下操作;先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把CPU的占有权交给次线程,否则继续运行原来的线程,所以yield()方法称为”退让”,它把运行机会让给了同等级的其他线程。

sleep 方法允许较低优先级的线程获得运行机会,但yield()方法执行时,当前线程仍处在可运行状态,所以不可能让出较低优先级的线程此时获取CPU占有权。在一个运行系统中,如果较高优先级的线程没有调用sleep方法,也没有受到I/O阻塞,那么较低优先级线程只能等待所有较高优先级的线程运行结束,方可有机会运行。

yield()只是使当前线程重新回到可执行状态,所有执行yield()的线程有可能在进入到可执行状态后马上又被执行,所以yield()方法只能使同优先级的线程有执行的机会

Original: https://www.cnblogs.com/liuxinyustu/p/8427002.html
Author: liuxinyu123
Title: java线程中yield(),sleep(),wait()区别详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/538521/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【B站】Java自学精选视频,收藏起来慢慢学

    ​现在学习Java的小伙伴越来越多,Java也确实有它独特的魅力并且迎合大中企业需求,而且就业前景好。 2022年了,希望你们能够快速成长,所以我今天精心挑选了一些java相关的视…

    Java 2023年6月7日
    085
  • 是时候优雅的和NullPointException说再见了

    是时候优雅的和NullPointException说再见了☝️☝️☝️☝️☝️☝️☝️☝️☝️☝️☝️☝️☝️☝️☝️☝️最近在参加原创投稿比赛,本篇文章如果对你有帮助的话,欢迎帮…

    Java 2023年6月7日
    0102
  • Spring 是怎么处理循环依赖的?

    Java语法中的循环依赖 首先看一个使用构造函数的循环依赖,如下: public class ObjectA { private ObjectB b; public ObjectA…

    Java 2023年6月8日
    074
  • 使用Jasypt对SpringBoot配置文件加密(转)

    <span class="hljs-tag"><<span class="hljs-name">depende…

    Java 2023年5月30日
    074
  • SpringBoot:同一个类中调用另一个方法没有触发 Spring AOP

    考虑如下一个例子: 在这个例子中, 我们定义了一个注解 MyMonitor, 这个是一个方法注解, 我们的期望是当有此注解的方法被调用时, 需要执行指定的切面逻辑, 即执行 MyA…

    Java 2023年5月30日
    0113
  • js实现浏览器后退页面刷新

    最近在开发中遇到一个问题: 在一个列表页面,点击进入详情,详情页面对其状态操作,其详情页面有做修改,然后点击浏览器后退,返回到列表页,在列表页面状态还是操作之前的,为解决状态统一需…

    Java 2023年6月8日
    0109
  • 解决latex数学公式渲染不正确及行内公式中文渲染乱码问题

    问题 之前数学OCR渲染数学公式用的 katex 来渲染,前端解决方案,我们的进行公式编写的时候是需要输入中文的,如: Fe_{2}O_{3} + 3 C O \stackrel{…

    Java 2023年6月7日
    0123
  • 希尔排序(java实现)

    一、概念及其介绍 希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。 希尔排序又称缩小增量排序,因 DL.Shell 于 1959 年提出而得名。 …

    Java 2023年6月5日
    086
  • pyhon——进程线程、与协程基础概述

    一直以来写博客都是实用主义者,只写用法,没信心写原理,但是每一次写作业的过程都有一种掘地三尺的感觉,终于,写博客困难症重症患者经历了漫长的思想斗争,还是决定把从网上淘到的各种杂货和…

    Java 2023年5月30日
    084
  • getting-started-with-mqtt

    A variety of MQTT client implementations are available for most of the popular operating s…

    Java 2023年5月29日
    094
  • springboot 配置热部署

    boot-devtools官方文档:https://docs.spring.io/spring-boot/docs/current/reference/html/using-boo…

    Java 2023年5月30日
    081
  • rabbitmq安装

    rabbitmq简介 rabbitmq安装 rabbitmq是erlang语言开发的,rabbitmq安装需要先安装erlang,再安装rabbitmq; ​ 官方网址: 双击安装…

    Java 2023年6月16日
    074
  • Spring源码分析(一)-Spring源码编译

    1 下载源码 1.1 fork源码 由于从github网络下载太慢,就直接在gitee下载了gitee源码镜像,fork主要是为了可以添加注释 2.2 下载源码 将fork的源码c…

    Java 2023年6月8日
    095
  • 你的博客被搜索引擎收录了吗?

    持续原创输出,点击上方蓝字关注我 前言 如何判断自己的博客被百度收录了? 如何操作? 准备一个百度站长账号 验证网站所有权 HTML验证 生成站点地图 如何自动推送? 总结 大部分…

    Java 2023年6月14日
    080
  • 附003.Nginx全系列大总结

    Nginx全系列总结如下,后期不定期更新。 欢迎基于学习、交流目的的转载和分享,禁止任何商业盗用,同时希望能带上原文出处,尊重ITer的成果,也是尊重知识。 若发现任何错误或纰漏,…

    Java 2023年5月30日
    0106
  • Git命令备忘录

    前言 基本内容 开始之前 基础内容 基础概念 基础命令 远程仓库 分支管理 基本命令 stash命令 rebase命令 冲突问题 标签管理 前言 Git在平时的开发中经常使用,整理…

    Java 2023年6月10日
    071
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球