多线程在面试中是非常受欢饮的题目,我个人认为我们很少有机会能够真正的用到复杂的多线程(我在7年前使用过一次),熟悉这些概念能够增加你的信心,先前,我已经讨论了一个相似的问题,wait()和sleep()的区别。现在我们讨论一下join()和yield()的区别。坦白的讲,我在实际中比没有用过这两种方法,如果你觉得有问题请在评论中提出来

java 线程调度的背景

java虚拟机要求在多线程中实现 preemptive和priority-based调度,这意味着java中每一个线程被分配了特定的优先级,正整数在定义好的范围内不断减。优先级可以通过开发者改变但是java虚拟机从不改变线程的优先级,即使线程已经运行了一段时间。
优先级的值很重要,因为这是java虚拟机和底部的操作系统的契约,操作系统必须选择一个最高优先级的java线程运行。这就是我们平时讲的java实现了一个priority-based的调度。调度的实现使用的是preemptive方式,也就是说高优先级的线程来到之后,不管低优先级的线程是否运行线程都会中断。然而和操作系统间的契约并不是绝对的,操作系统也可以选择低优先级的线程运行【我很讨厌多线程的这点,没有什么是保证的】

理解线程的优先级

理解线程的优先级是学习多线程特别是yield怎么工作的下一个重要的步骤。
1、在不指定的情况下,所有的线程的优先级都是正常的。
2、优先级的范围从1到10,10是最高优先级,1是最低优先级,5是正常优先级。
3、最高优先级的线程有执行的趋向,但是不能保证这一线程一定会在它开始的时候执行。
4、当前执行的线程和线程池中等待的线程相比或许有比较高的优先级。
5、线程调度决定哪个线程执行
6、t.setPriority()可以被用来设置线程的优先级
7、线程的优先级应该在start()方法调用之前被设置
8、你可以使用常量MIN_PRIORITY,MAX_PRIORITY and NORM_PRIORITY来设置优先级
现在我们队对线程的调度和线程的优先级有了基本的了解,开始进入主题

yield方法

理论上讲,yield的意思是松开,放弃或者是屈服。一个yielding的线程告诉虚拟机它允许其他的线程被调度它现在所在的位置,这意味着它没有严格的做一些事情。注意这只是一个线索,没有保证什么事情。
在Thread.java中yield是这样定义的
/*** A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore* this hint. Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilize a CPU.* Its use should be combined with detailed profiling and benchmarking to ensure that it actually has the desired effect.*/public static native void yield();

我们列一下上边定义的一些重要的点

1、yield的是静态方法也是native方法
2、yield告诉正在执行的线程给线程池中有相同优先级的线程一个机会
3、yield不能保证正在执行的线程立刻变成Runnable状态
4、它仅仅可以使一个线程从running状态变成Runnable状态,而不是wait或者blocked状态

yield()方法使用的例子

在下边的程序中,我创建了两个线程一个是producer一个是consumer。producer设置最小的优先级,consumer设置最高的优先级,在使用和不使用yield方法的条件下运行下边的代码,尽管输出有时候会改变,但是通常情况下首先是consumer全部打印,其次是producer全部打印
使用yield方法,一次打印一行,然后其他线程运行
package test.core.threads;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();}
}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();}}
}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();}}
}

不使用yield方法的输出

I am Consumer : Consumed Item 0
 I am Consumer : Consumed Item 1
 I am Consumer : Consumed Item 2
 I am Consumer : Consumed Item 3
 I am Consumer : Consumed Item 4
 I am Producer : Produced Item 0
 I am Producer : Produced Item 1
 I am Producer : Produced Item 2
 I am Producer : Produced Item 3
 I am Producer : Produced Item 4
使用yield方法的输出
I am Producer : Produced Item 0
 I am Consumer : Consumed Item 0
 I am Producer : Produced Item 1
 I am Consumer : Consumed Item 1
 I am Producer : Produced Item 2
 I am Consumer : Consumed Item 2
 I am Producer : Produced Item 3
 I am Consumer : Consumed Item 3
 I am Producer : Produced Item 4
 I am Consumer : Consumed Item 4

join()方法

线程实例的join()方法可以被用来join到线程执行的开始和其他线程执行的结束,所以直到其他线程运行结束这个线程才会执行。如果join的方法在线程实例中被调用,当前运行的线程会被堵塞,直到线程实例运行完成
//Waits for this thread to die.public final void join() throws InterruptedException

在join方法中设定超时,可以设定在指定的时间内无效。当超时到达,主线程和任务线程都可能被执行,但是,因为有sleep,join需要根据OS的时间规定来执行,所以你不应该假定线程和你指定的时间是一样的

和sleep一样,Join相应中断

join方法使用的例子

package test.core.threads;public class JoinExample
{public static void main(String[] args) throws InterruptedException{Thread t = new Thread(new Runnable(){public void run(){System.out.println("First task started");System.out.println("Sleeping for 2 seconds");try{Thread.sleep(2000);} catch (InterruptedException e){e.printStackTrace();}System.out.println("First task completed");}});Thread t1 = new Thread(new Runnable(){public void run(){System.out.println("Second task completed");}});t.start(); // Line 15t.join(); // Line 16t1.start();}
}Output:First task started
Sleeping for 2 seconds
First task completed
Second task completed
thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。 

这就是一个很小但是很重要的概念的全部。

原文地址:http://howtodoinjava.com/2014/06/03/difference-between-yield-and-join-in-threads-in-java/
也可参考:http://uule.iteye.com/blog/1101994
关注我,获取400个的赚钱金点子,轻松开启程序员的副业生涯

java线程中yield()和join()的区别相关推荐

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

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

  2. 线程中start()与run()的区别

    每个线程都有要执行的任务.线程的任务处理逻辑可以在Tread类的run实例方法中直接实现或通过该方法进行调用,因此 run()相当于线程的任务处理逻辑的入口方法,它由Java虚拟机在运行相应线程时直接 ...

  3. java线程礼让yield

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

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

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

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

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

  6. 线程中的同步和异步的区别

    线程中的同步和异步的区别 一.同步        所谓同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作.是多个线程同时访问同一资源,等待资源访问结束,浪费时间,效率不 ...

  7. Java线程中sleep()、wait()和notify()、suspend()和resume()、yield()、join()、interupt()的用法和区别

    从操作系统的角度讲,os会维护一个ready queue(就绪的线程对列).并在某一时刻CPU只为ready queue中位于队列头部的线程服务.但是当前正在被服务的线程可能觉得cpu的服务质量不够好 ...

  8. Java线程中wait、await、sleep、yield、join用法总结

    文章目录 一.wait().notify().notifyAll()用法 二.await().signal().signalAll()用法 三 .yield().join()用法 四.wait().a ...

  9. Java线程中,Blocked,Wait,以及TIMED_WAIT的区别

    根据jdk1.6的api,java的Thread类,定义了六个状态: 线程状态.线程可以处于下列状态之一: NEW 至今尚未启动的线程处于这种状态. RUNNABLE 正在 Java 虚拟机中执行的线 ...

最新文章

  1. 溯因推理:人工智能的盲点
  2. Android 实现布局动态加载
  3. hht时频谱 matlab 乱序_频谱、能量谱、功率谱的区别与联系
  4. 面试官:new一个对象的过程中发生了什么
  5. 安装Google Object Detection API
  6. 《蘑菇街编程题》回文串
  7. java entitymanager类_如何在Java JDBC EntityManagerFactory类中设置实体的ID?
  8. oracle foreign 查询,ORACLE foreign key
  9. 实战 RocketMQ 流量削峰,怎么能错过这一篇!
  10. ES6新特性_变量的解构赋值---JavaScript_ECMAScript_ES6-ES11新特性工作笔记006
  11. C++横板格斗小游戏(基于Easyx图形库)
  12. 《平凡的世界》造就不平凡的人生 --路遥
  13. outlook安全模式修复_Outlook Com安全漏洞Microsoft无法修复
  14. java root权限_Android应用获取Root权限
  15. mysql忘记密码问题
  16. AirDisk存宝 【S3和S6后面的USB口是用来干嘛的?有什么作用?】
  17. 对WEB应用的粗浅理解
  18. 股市跌跌不休,IPO能救市吗?
  19. org.hibernate.MappingException: Unknown entity: dxm.com.vo.User
  20. 想骂人!开发语言不能统一成一个么?

热门文章

  1. h5画三角形_H5如何在网页中绘制三角形,值得一看
  2. 修改密码后,mac的邮箱登录不上(已解决)
  3. 嘴上老喊辞职的人总也不走,如何看待这种现象?
  4. 对于任一整数n,符号函数sign(n)的定义如下
  5. 改进YOLOv5 | Stand-Alone Self-Attention | 针对视觉任务的独立自注意力层 | 搭建纯注意力FPN+PAN结构
  6. 报错:‘Concatenate’layer requires inputs with matching shapes expect for the concat axis. 解决思路
  7. 蚂蚁金服面试题和答案
  8. snipaste滚动截图方法_截图、拼图、图像编辑太麻烦?试试这款免费截图软件
  9. 关于MSP430单片机串口通信数据丢失问题
  10. 关于Banner制作有感(antD+react)