对于很多初学 Java 线程的小伙伴们,很容易将 Thread 类里的 yield() 方法理解错误,或者理解得不够透彻,先看下源码:

public static native void yield();

是的,你没看错,Thread 类源码中定义的这个方法没有方法体,native 关键字修饰的方法表示原生态方法,方法对应的实现不在这个类文件里,而是在用其他语言(如 C 和 C++)实现的文件中。Java 语言本身不能对操作系统底层进行访问和操作(但可以通过 JNI 接口调用其他语言来实现对底层的访问)。所以,想要知道并理解 yield() 方法的具体实现过程,于初学者来说并没有必要。虽然“无代码无真相”,但采用大白话的解释或许更加通俗易懂吧。

Java线程调度的一点背景

在各种各样的线程中,Java 虚拟机必须实现一个有优先权的、基于优先级的调度程序。这意味着 Java 程序中的每一个线程被分配到一定的优先权,使用定义好的范围内的一个正整数表示。优先级可以被开发者改变。即使线程已经运行了一定时间,Java 虚拟机也不会改变其优先级。

优先级的值很重要,因为 Java 虚拟机和下层的操作系统之间的约定是操作系统必须选择有最高优先权的 Java 线程运行。所以我们说 Java 实现了一个基于优先权的调度程序。该调度程序使用一种有优先权的方式实现,这意味着当一个有更高优先权的线程到来时,无论低优先级的线程是否在运行,都会中断(抢占)它。这个约定对于操作系统来说并不总是这样,这意味着操作系统有时可能会选择运行一个更低优先级的线程。

理解线程的优先权

接下来,理解线程优先级是多线程学习很重要的一步,尤其是了解 yield() 函数的工作过程:

1、记住当线程的优先级没有指定时,所有线程都携带普通优先级。

2、优先级可以用从 1 到 10 的范围指定。10 表示最高优先级,1 表示最低优先级,5 是普通优先级。

3、记住优先级最高的线程在执行时被给予优先。但是不能保证线程在启动时就进入运行状态。

4、与在线程池中等待运行机会的线程相比,当前正在运行的线程可能总是拥有更高的优先级。

5、由调度程序决定哪一个线程被执行。

6、t.setPriority() 用来设定线程的优先级。

7、记住在线程 start() 方法被调用之前,线程的优先级应该被设定。

8、你可以使用常量,如 MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY 来设定优先级。

现在,我们对线程调度和线程优先级有一定理解了,进入主题。

Thread.yield() 方法会使当前线程从执行状态(运行状态)变为可执行状态(就绪状态)。CPU 会从众多的可执行态里选择,也就是说,当前也就是刚刚调用 yield() 方法的那个线程还是有可能会被再次继续执行的。yield() 方法并不是让当前线程暂停,让出时间片去执行其他线程,而在下一次时间片内就一定不会执行了(当前线程只是转换为就绪状态,在下一个本该是自己的却让给其他线程的时间片内也可能再次继续被执行)。

很多人将 yield 翻译成线程让步。顾名思义,就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的一段时间片让给自己或者其它的线程运行。

看如下例子:

public class TestYield {

public static void main(String[] args) {

MyThread3 t1 = new MyThread3("t1");

MyThread3 t2 = new MyThread3("t2");

t1.start();

t2.start();

}

}

class MyThread3 extends Thread {

MyThread3(String s) {

super(s);

}

public void run() {

for (int i = 1; i <= 100; i++) {

System.out.println(getName() + ": " + i);

if (i % 10 == 0) {

yield();

}

}

}

}

再看运行结果:

.

.

.

t1: 8

t1: 9

t1: 10

t2: 6

t1: 11

.

.

.

t1: 18

t1: 19

t1: 20

t1: 21

t1: 22

.

.

.

t1: 10 后 t2: 6;t1: 20 后 t1: 21。

总结后可得以下重要的几点:

1、yield 是一个静态的原生(native)方法。

2、yield 告诉当前正在执行的线程把运行机会交给线程池中拥有相同优先级的线程。

3、yield 不能保证使得当前正在运行的线程迅速转换到可运行的状态。

4、它仅能使一个线程从运行状态转到可运行状态,而不是等待或阻塞状态。

java yeild_Java 中 Thread.yield() 方法详解相关推荐

  1. java多线程中的join方法详解

    java多线程中的join方法详解 方法Join是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答. 自从接触Java多线程,一直对Join理解不了.JDK是这样说的:join p ...

  2. java richtextbox_C#中richtextbox使用方法详解

    C#中RichTextBox使用方法和TextBox基本一样,只不过RichText除了TXT外,还支持RTF格式的文档.本文详细介绍RichTextBox的使用方法供大家参考,具体如下: 一.Ric ...

  3. Java线程中的sleep方法详解

    文章目录 1.关于线程的sleep方法 2.分析哪个线程休眠的 3.终止线程的休眠 4.终止线程 强行终止线程 合理的终止线程 1.关于线程的sleep方法 static void sleep(lon ...

  4. java getproperty_java中System.getProperty()方法详解

    System.out.println("java版本号:" + System.getProperty("java.version")); // java版本号 ...

  5. Java中的main()方法详解

    源文作者:leizhimin    源文链接:http://lavasoft.blog.51cto.com/62575/53263 源文作者版权申明: 版权声明:原创作品,允许转载,转载时请务必以超链 ...

  6. java中main是什么_Java中的main()方法详解

    在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是 ...

  7. 好程序员Java学习路线分享finalize()方法详解

    好程序员Java学习路线分享finalize()方法详解,前言,finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法.. fi ...

  8. Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)

    Python 在子类中调用父类方法详解(单继承.多层继承.多重继承)   by:授客 QQ:1033553122   测试环境: win7 64位 Python版本:Python 3.3.5 代码实践 ...

  9. php 文件扫描去重,PHP中的去重方法详解和文件下载

    本文主要和大家分享PHP中的去重方法详解和文件下载,在php中文件导入过程中,经常会遇到重复事件,那么就需要我们去重,然后进行下载. 1.思想 先设置一个存储主键数组,和一个空数组.解析文件,然后看要 ...

最新文章

  1. oracle修改连接数
  2. AjaxPro2在Asp.net中的基本用法
  3. 十四、去年写的Numpy使用方法梳理,2020年5月13日整理
  4. ORACLE数据迁移参考
  5. CCNP-EIGRP不等价负载均衡
  6. QEMU 网络虚拟化
  7. 前端样板资源概览及总评
  8. 进程间通信(匿名管道)
  9. mysql配置文件编写_MySQL5.7.28 配置文件编写
  10. python string转int_Python编程入门:time模块常用技巧
  11. http之url和uri
  12. 【游戏开发实战】Unity从零做一个任务系统,人生如梦,毕业大学生走上人生巅峰(含源码工程 | 链式任务 | 主线支线)
  13. Java项目的项目流程(快速了解)
  14. mysql 约束 分类,MySQL约束类型及举例介绍
  15. 三、box 盒子模型
  16. 什么是ACL和RBAC
  17. 英特尔傲腾DC P4800X有哪些适用场景?
  18. 我是如何利用Python下载酷狗音乐的
  19. 大数据心法来了!一站式玩转MaxCompute,还有开发者资源等你领!
  20. Notifiction

热门文章

  1. Python GUI
  2. haskell vscode下的环境搭配(包含各种坑的解决办法)
  3. mongo04---基本查询
  4. Android 中this、getContext()、getApplicationContext()、getApplication()、getBaseContext() 之间的区别...
  5. 中国计算机学会通讯下载工具(简易爬虫)
  6. MySQL数据库datetime类型不能为空值的问题
  7. 让你的php命令行程序处理管道数据
  8. 更新 PORTS-Tree 且升级已安装的软件[zt]
  9. 计算机参评高校168所,168所大学排行榜单!计算机科学与技术专业哪些高校专业实力最强!...
  10. SpringBoot项目 整合 JacksonXml