Thread.join()方法解析

API:

join

public final void join()
                throws InterruptedException
等待该线程终止。


抛出:
InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的 中断状态 被清除。

join

public final void join(long millis)
                throws InterruptedException
等待该线程终止的时间最长为  millis 毫秒。超时为  0 意味着要一直等下去。


参数:
millis - 以毫秒为单位的等待时间。
抛出:
InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的 中断状态 被清除。

join

public final void join(long millis,
                       int nanos)
                throws InterruptedException
等待该线程终止的时间最长为  millis 毫秒 +  nanos 纳秒。


参数:
millis - 以毫秒为单位的等待时间。
nanos - 要等待的 0-999999 附加纳秒。
抛出:
IllegalArgumentException - 如果 millis 值为负,则 nanos 的值不在 0-999999 范围内。
InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的 中断状态 被清除。

解析

Thread.join(),是用来指定当前主线程等待其他线程执行完毕后,再来继续执行Thread.join()后面的代码


例1:

[java]  view plain  copy
 print ?
  1. package com.example;  
  2.   
  3. import java.util.Date;  
  4. import java.util.concurrent.TimeUnit;  
  5.   
  6. public class DataSourcesLoader implements Runnable{  
  7.   
  8.     @Override  
  9.     public void run() {  
  10.         System.out.printf("Beginning data sources loading: %s\n",new Date());  
  11.         try {  
  12.           TimeUnit.SECONDS.sleep(4);  
  13.         } catch (InterruptedException e) {  
  14.           e.printStackTrace();  
  15.         }  
  16.         System.out.printf("Data sources loading has finished: %s\n",new Date());  
  17.     }  
  18.   
  19.     public static void main(String[] args){  
  20.         DataSourcesLoader dsLoader = new DataSourcesLoader();  
  21.         Thread thread1 = new Thread(dsLoader,"DataSourceThread");  
  22.           
  23.         thread1.start();  
  24.           
  25.         try {  
  26.             thread1.join();  
  27.           } catch (InterruptedException e) {  
  28.             e.printStackTrace();  
  29.           }  
  30.             
  31.           System.out.printf("Main: Configuration has been loaded: %s\n",new Date());  
  32.     }  
  33.   
  34. }  
执行结果:

[java]  view plain  copy
 print ?
  1. Beginning data sources loading: Fri Nov 14 14:27:31 CST 2014  
  2. Data sources loading has finished: Fri Nov 14 14:27:35 CST 2014  
  3. Main: Configuration has been loaded: Fri Nov 14 14:27:35 CST 2014  
如果去掉thread1.join(),执行的结果如下:

[java]  view plain  copy
 print ?
  1. Main: Configuration has been loaded: Fri Nov 14 14:28:33 CST 2014  
  2. Beginning data sources loading: Fri Nov 14 14:28:33 CST 2014  
  3. Data sources loading has finished: Fri Nov 14 14:28:37 CST 2014  
通过结果,就可以很明显的说明上面红字的部分:“ 再来继续执行Thread.join()后面的代码

例2:

[java]  view plain  copy
 print ?
  1. package com.example;  
  2.   
  3. import java.util.Date;  
  4. import java.util.concurrent.TimeUnit;  
  5.   
  6. public class DataSourcesLoader implements Runnable{  
  7.   
  8.     @Override  
  9.     public void run() {  
  10.         System.out.printf("Beginning data sources loading: %s\n",new Date());  
  11.         try {  
  12.           TimeUnit.SECONDS.sleep(4);  
  13.         } catch (InterruptedException e) {  
  14.           e.printStackTrace();  
  15.         }  
  16.         System.out.printf("Data sources loading has finished: %s\n",new Date());  
  17.     }  
  18.   
  19.     public static void main(String[] args){  
  20.         DataSourcesLoader dsLoader = new DataSourcesLoader();  
  21.         Thread thread1 = new Thread(dsLoader,"DataSourceThread");  
  22.           
  23.         thread1.start();  
  24.           
  25.         try {  
  26.             thread1.join(3000);  
  27.           } catch (InterruptedException e) {  
  28.             e.printStackTrace();  
  29.           }  
  30.             
  31.           System.out.printf("Main: Configuration has been loaded: %s\n",new Date());  
  32.     }  
  33.   
  34. }  

这里使用的是:
[java]  view plain  copy
 print ?
  1. thread1.join(3000);  
这句话的意思是,只要满足下面2个条件中的一个时,主线程就会继续执行thread.join()后面的代码:

条件1:thread1 执行完毕;

条件2:已经等待 thread1 执行了3000ms.

例子中,thread1 自身的执行时间是4s,而设置的等待时间是3s,所以得到的执行结果如下,thread1还没有执行完,主线程就开始执行后面的代码,因为 thread1 等待的时间已经超时了:

[java]  view plain  copy
 print ?
  1. Beginning data sources loading: Fri Nov 14 14:35:45 CST 2014  
  2. Main: Configuration has been loaded: Fri Nov 14 14:35:48 CST 2014  
  3. Data sources loading has finished: Fri Nov 14 14:35:49 CST 2014  



那么结合上面的2个例子,我们可以推断出下面代码的执行结果了:

例3:

[java]  view plain  copy
 print ?
  1. package com.example;  
  2.   
  3. import java.util.Date;  
  4. import java.util.concurrent.TimeUnit;  
  5.   
  6. public class DataSourcesLoader implements Runnable{  
  7.   
  8.     @Override  
  9.     public void run() {  
  10.         System.out.printf("Beginning data sources loading: %s\n",new Date());  
  11.         try {  
  12.           TimeUnit.SECONDS.sleep(4);  
  13.         } catch (InterruptedException e) {  
  14.           e.printStackTrace();  
  15.         }  
  16.         System.out.printf("Data sources loading has finished: %s\n",new Date());  
  17.     }  
  18.   
  19. }  

[java]  view plain  copy
 print ?
  1. package com.example;  
  2.   
  3. import java.util.Date;  
  4. import java.util.concurrent.TimeUnit;  
  5.   
  6. public class NetworkConnectionsLoader implements Runnable{  
  7.   
  8.     @Override  
  9.     public void run() {  
  10.         System.out.printf("Beginning network connect loading: %s\n",new Date());  
  11.         try {  
  12.           TimeUnit.SECONDS.sleep(6);  
  13.         } catch (InterruptedException e) {  
  14.           e.printStackTrace();  
  15.         }  
  16.         System.out.printf("Network connect loading has finished: %s\n",new Date());  
  17.           
  18.     }  
  19.       
  20.     public static void main(String[] args){  
  21.         DataSourcesLoader dsLoader = new DataSourcesLoader();  
  22.         Thread thread1 = new Thread(dsLoader,"DataSourceThread");  
  23.           
  24.         NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();  
  25.         Thread thread2 = new Thread(ncLoader,"NetworkConnectionLoader");  
  26.           
  27.         thread1.start();  
  28.         thread2.start();   
  29.           
  30.         try {  
  31.             thread1.join();  
  32.             thread2.join(1900);  
  33.           } catch (InterruptedException e) {  
  34.             e.printStackTrace();  
  35.           }  
  36.             
  37.           System.out.printf("Main: Configuration has been loaded: %s\n",new Date());  
  38.     }  
  39.   
  40. }  
执行结果:

[java]  view plain  copy
 print ?
  1. Beginning data sources loading: Fri Nov 14 14:39:20 CST 2014  
  2. Beginning network connect loading: Fri Nov 14 14:39:20 CST 2014  
  3. Data sources loading has finished: Fri Nov 14 14:39:24 CST 2014  
  4. Main: Configuration has been loaded: Fri Nov 14 14:39:26 CST 2014  
  5. Network connect loading has finished: Fri Nov 14 14:39:26 CST 2014  

注意:如果把例3的 thread2.join(1900) 部分修改为:

[java]  view plain  copy
 print ?
  1. thread2.join(3000);  
结果会和上面的一样吗?

根据我最开始指出的“ Thread.join(),是用来指定当前主线程等待其他线程执行完毕后,再来继续执行Thread.join()后面的代码

我们可以看到,执行结果会有差别:

[java]  view plain  copy
 print ?
  1. Beginning data sources loading: Fri Nov 14 14:41:21 CST 2014  
  2. Beginning network connect loading: Fri Nov 14 14:41:21 CST 2014  
  3. Data sources loading has finished: Fri Nov 14 14:41:25 CST 2014  
  4. Network connect loading has finished: Fri Nov 14 14:41:27 CST 2014  
  5. Main: Configuration has been loaded: Fri Nov 14 14:41:27 CST 2014  

至于为什么会有这个差别,我上面也已经说明了,我想这个应该不难理解。

你可能感兴趣的:(java,线程)