Java线程中yield与join方法的区别

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

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

理解线程的优先权

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

记住当线程的优先级没有指定时,所有线程都携带普通优先级。
优先级可以用从1到10的范围指定。10表示最高优先级,1表示最低优先级,5是普通优先级。
记住优先级最高的线程在执行时被给予优先。但是不能保证线程在启动时就进入运行状态。
与在线程池中等待运行机会的线程相比,当前正在运行的线程可能总是拥有更高的优先级。
由调度程序决定哪一个线程被执行。
t.setPriority()用来设定线程的优先级。
记住在线程开始方法被调用之前,线程的优先级应该被设定。
你可以使用常量,如MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY来设定优先级
现在,当我们对线程调度和线程优先级有一定理解后,让我们进入主题。

yield()方法使用示例

在下面的示例程序中,我随意的创建了名为生产者和消费者的两个线程。生产者设定为最小优先级,消费者设定为最高优先级。在Thread.yield()注释和非注释的情况下我将分别运行该程序。
没有调用yield()方法时,虽然输出有时改变,但是通常消费者行先打印出来,然后事生产者。
调用yield()方法时,两个线程依次打印,然后将执行机会交给对方,一直这样进行下去。

package com.itcast.demo;

public class Producer extends Thread {
public void run()
{
for (int i = 0; i < 5; i++)
{
System.out.println("I am Producer : Produced Item " + i);
Thread.yield();
}
}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
package com.itcast.demo;

public class Consumer extends Thread {
public void run()
{
for (int i = 0; i < 5; i++)
{
System.out.println("I am Consumer : Consumed Item " + i);
Thread.yield();
}
}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
package com.itcast.demo;

public class YieldExample {
public static void main(String[] args) {
Thread producer = new Producer();
Thread consumer = new Consumer();

  producer.setPriority(Thread.MIN_PRIORITY); //Min Priorityconsumer.setPriority(Thread.MAX_PRIORITY); //Max Priorityproducer.start();consumer.start();
}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

上述程序没调用yield()方法情况下的输出:

上述程序在调用yield()方法情况下的输出:

yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。
结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

join()方法
线程实例的方法join()方法可以使得一个线程在另一个线程结束后再执行。如果join()方法在一个线程实例上调用,当前运行着的线程将阻塞直到这个线程实例完成了执行。

package com.itcast.demo2;

public class ThreadImp implements Runnable {

@Override
public void run() {try {System.out.println("Begin ThreadImp");Thread.sleep(5000);//休息5sSystem.out.println("End ThreadImp");} catch (Exception e) {System.out.println(e);}
}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
package com.itcast.demo2;

public class JoinTest {
public static void main(String[] args) {
Thread t = new Thread(new ThreadImp());
t.start();
try {
t.join(1000);//主程序等待t结束,只等1s
if(t.isAlive()){
System.out.println(“t has not finished”);
}else{
System.out.println(“t has finished”);
}
System.out.println(“Joinfinished”);
} catch (Exception e) {
System.out.println(e);
}
}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

总结
yield方法(让给相同级别的线程执行,如果没有相同级别的,线程继续运行,不退出)

join方法(跟高级别或同级线程别抢资源)

Java线程中yield与join方法的区别相关推荐

  1. java线程 yield_Java线程中yield与join方法的区别

    长期以来,多线程问题颇为受到面试官的青睐.虽然我个人认为我们当中很少有人能真正获得机会开发复杂的多线程应用(在过去的七年中,我得到了一个机会),但是理解多线程对增加你的信心很有用.之前,我讨论了一个w ...

  2. java线程中yield()和join()的区别

    多线程在面试中是非常受欢饮的题目,我个人认为我们很少有机会能够真正的用到复杂的多线程(我在7年前使用过一次),熟悉这些概念能够增加你的信心,先前,我已经讨论了一个相似的问题,wait()和sleep( ...

  3. java foward_java 中sendredirect()和forward()方法的区别

    HttpServletResponse.sendRedirect与RequestDispatcher.forward方法都可以实现获取相应URL资源. sendRedirect实现请求重定向,forw ...

  4. java wait 参数_java中wait()和join()方法的区别是什么

    java中wait()和join()方法的区别是:存在不同的java包中:wait()方法用于线程间通信,它所施加的等待状态的线程可以被启动:join()方法用于在多个线程之间添加排序,它所施加的等待 ...

  5. java有push方法么_[Java教程]js中push和join方法使用介绍

    [Java教程]js中push和join方法使用介绍 0 2013-10-09 07:00:17 push和join方法想必大家并不陌生吧,在本文将为大家详细介绍下js中的push和join方法的使用 ...

  6. left join 和join区别_sleep、yield、join方法简介与用法 sleep与wait区别 多线程中篇

    Object中的wait.notify.notifyAll,可以用于线程间的通信,核心原理为借助于监视器的入口集与等待集逻辑 通过这三个方法完成线程在指定锁(监视器)上的等待与唤醒,这三个方法是以锁( ...

  7. java线程礼让yield

    java线程礼让yield 1.yield方法 ​ 使用Thread类的静态方法yield可以对当前线程进行礼让,yield方法使线程从运行状态转换到就绪状态, 这与sleep方法对比,sleep是使 ...

  8. java 线程 获取消息_获取java线程中信息

    怎样获取java线程中信息? 在进行多线程编程中,比较重要也是比较困难的一个操作就是如何获取线程中的信息.大多数人会采取比较常见的一种方法就是将线程中要返回的结果存储在一个字段中,然后再提供一个获取方 ...

  9. java 线程中创建线程_如何在Java 8中创建线程安全的ConcurrentHashSet?

    java 线程中创建线程 在JDK 8之前,还没有办法在Java中创建大型的线程安全的ConcurrentHashSet. java.util.concurrent包甚至没有一个名为Concurren ...

  10. 多线程中Thread的join方法

    多线程中Thread的join方法 join简介 join方法是Thread类中的一个方法,该方法的定义是等待该线程执行直到终止.其实就说join方法将挂起调用线程的执行,直到被调用的对象完成它的执行 ...

最新文章

  1. 《HTML5 Canvas开发详解》——1.7 2D上下文及其当前状态
  2. 第13章 Kotlin 集成 SpringBoot 服务端开发(1)
  3. Leetcode记录
  4. 北京排查利用数据中心挖矿,IDC矿场受影响较大
  5. linux中anconda python集成环境配置
  6. android 仿ios tabs,React Native兼容iOS Android的TabBar
  7. 超轻简洁个人引导页网站源码
  8. 第十三篇:multimap容器和multiset容器中的find操作
  9. 【实习之T100开发】T100 Q查询开发流程
  10. IDC带宽测试几款软件(Multiping pingPlotter TracertGUI )
  11. Pure-ftpd无法连接到服务器 425错误
  12. EntityTransaction
  13. 腾讯云和阿里云mysql性能对比_阿里云腾讯云服务器官方性能及实际体验对比
  14. PHY寄存器驱动调试总结
  15. podman的配置以及命令详解
  16. UIkit框架之轮播特效
  17. package.json bin的作用
  18. git 仓库分支多文件夹管理
  19. jena java_java – 使用Jena查询wikidata
  20. 微信小程序实现缓存过期时间

热门文章

  1. 整合dubbo报错严重 Exception sending context initialized event to listener instance of class 解决
  2. MATLAB车辆路径或物流分配或生产调度问题实例设计和代码
  3. 制作rime配色的fcitx皮肤
  4. Pycharm this applicatation failed to start because it could not find or laod the qt plaform plugin
  5. 蚌埠住了,让我虎躯一震的代码!
  6. Android-资深架构师的成长之路(技术详细介绍),flutterui套件
  7. luogu P2123 皇后游戏
  8. c语言三重积分程序求法,D9_3三重积分[同济大学高等数学]..docx
  9. 各类重积分 | 二重积分、三重积分、线面积分 —— 大总结
  10. prometheus 告警配置以及配置项解释