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

Java线程调度的一点背景

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

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

 

理解线程的优先权

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

  1. 记住当线程的优先级没有指定时,全部线程都携带普通优先级。
  2. 优先级能够用从1到10的范围指定。10表示最高优先级,1表示最低优先级,5是普通优先级。
  3. 记住优先级最高的线程在执行时被给予优先。可是不能保证线程在启动时就进入运行状态。
  4. 与在线程池中等待运行机会的线程相比,当前正在运行的线程可能老是拥有更高的优先级。
  5. 由调度程序决定哪个线程被执行。
  6. t.setPriority()用来设定线程的优先级。
  7. 记住在线程开始方法被调用以前,线程的优先级应该被设定。
  8. 你可使用常量,如MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY来设定优先级

如今,当咱们对线程调度和线程优先级有必定理解后,让咱们进入主题。学习

yield()方法

理论上,yield意味着放手,放弃,投降。一个调用yield()方法的线程告诉虚拟机它乐意让其余线程占用本身的位置。这代表该线程没有在作一些紧急的事情。注意,这仅是一个暗示,并不能保证不会产生任何影响。this

让咱们列举一下关于以上定义重要的几点:spa

  • Yield是一个静态的原生(native)方法
  • Yield告诉当前正在执行的线程把运行机会交给线程池中拥有相同优先级的线程。
  • Yield不能保证使得当前正在运行的线程迅速转换到可运行的状态
  • 它仅能使一个线程从运行状态转到可运行状态,而不是等待或阻塞状态.

yield()方法使用示例

在下面的示例程序中,我随意的建立了名为生产者和消费者的两个线程。生产者设定为最小优先级,消费者设定为最高优先级。在Thread.yield()注释和非注释的状况下我将分别运行该程序。没有调用yield()方法时,虽然输出有时改变,可是一般消费者行先打印出来,而后事生产者。操作系统

调用yield()方法时,两个线程依次打印,而后将执行机会交给对方,一直这样进行下去。线程

join()方法

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

1
2
3
//Waits for this thread to die.
 
public final void join() throws InterruptedException

在join()方法内设定超时,使得join()方法的影响在特定超时后无效。当超时时,主方法和任务线程申请运行的时候是平等的。然而,当涉及sleep时,join()方法依靠操做系统计时,因此你不该该假定join()方法将会等待你指定的时间。blog

像sleep,join经过抛出InterruptedException对中断作出回应。

 

 1 package test.core.threads;
 2  
 3 public class JoinExample
 4 {
 5    public static void main(String[] args) throws InterruptedException
 6    {
 7       Thread t = new Thread(new Runnable()
 8          {
 9             public void run()
10             {
11                System.out.println("First task started");
12                System.out.println("Sleeping for 2 seconds");
13                try
14                {
15                   Thread.sleep(2000);
16                } catch (InterruptedException e)
17                {
18                   e.printStackTrace();
19                }
20                System.out.println("First task completed");
21             }
22          });
23       Thread t1 = new Thread(new Runnable()
24          {
25             public void run()
26             {
27                System.out.println("Second task completed");
28             }
29          });
30       t.start(); // Line 15
31       t.join(); // Line 16
32       t1.start();
33    }
34 }
35  
36 Output:
37  
38 First task started
39 Sleeping for 2 seconds
40 First task completed
41 Second task completed
相关文章
相关标签/搜索