您的位置:首页 > 其它

Thread.join()方法解析

2017-03-10 19:43 441 查看

个人理解:

Thread.join();  谁调用,谁加入。
 程序执行到这一步的时候,调用此函数的线程直接撸进去干,顾名思义join。
Thread.join(3); 调用此函数的线程强行撸进去,时间限制3毫秒,3毫秒过后程序继续向下执行。
Thread.join(3,2);调用此函数的线程强行撸进去,时间限制3毫秒2纳秒,3毫秒+2纳秒过后程序继续向下执行。


以下为转载:

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?





package com.example;  

  

import java.util.Date;  

import java.util.concurrent.TimeUnit;  

  

public class DataSourcesLoader implements Runnable{  

  

    @Override  

    public void run() {  

        System.out.printf("Beginning data sources loading: %s\n",new Date());  

        try {  

          TimeUnit.SECONDS.sleep(4);  

        } catch (InterruptedException e) {  

          e.printStackTrace();  

        }  

        System.out.printf("Data sources loading has finished: %s\n",new Date());  

    }  

  

    public static void main(String[] args){  

        DataSourcesLoader dsLoader = new DataSourcesLoader();  

        Thread thread1 = new Thread(dsLoader,"DataSourceThread");  

          

        thread1.start();  

          

        try {  

            thread1.join();  

          } catch (InterruptedException e) {  

            e.printStackTrace();  

          }  

            

          System.out.printf("Main: Configuration has been loaded: %s\n",new Date());  

    }  

  

}  

执行结果:

[java] view
plain copy

 print?





Beginning data sources loading: Fri Nov 14 14:27:31 CST 2014  

Data sources loading has finished: Fri Nov 14 14:27:35 CST 2014  

Main: Configuration has been loaded: Fri Nov 14 14:27:35 CST 2014  

如果去掉thread1.join(),执行的结果如下:

[java] view
plain copy

 print?





Main: Configuration has been loaded: Fri Nov 14 14:28:33 CST 2014  

Beginning data sources loading: Fri Nov 14 14:28:33 CST 2014  

Data sources loading has finished: Fri Nov 14 14:28:37 CST 2014  

通过结果,就可以很明显的说明上面红字的部分:“再来继续执行Thread.join()后面的代码”

例2:

[java] view
plain copy

 print?





package com.example;  

  

import java.util.Date;  

import java.util.concurrent.TimeUnit;  

  

public class DataSourcesLoader implements Runnable{  

  

    @Override  

    public void run() {  

        System.out.printf("Beginning data sources loading: %s\n",new Date());  

        try {  

          TimeUnit.SECONDS.sleep(4);  

        } catch (InterruptedException e) {  

          e.printStackTrace();  

        }  

        System.out.printf("Data sources loading has finished: %s\n",new Date());  

    }  

  

    public static void main(String[] args){  

        DataSourcesLoader dsLoader = new DataSourcesLoader();  

        Thread thread1 = new Thread(dsLoader,"DataSourceThread");  

          

        thread1.start();  

          

        try {  

            thread1.join(3000);  

          } catch (InterruptedException e) {  

            e.printStackTrace();  

          }  

            

          System.out.printf("Main: Configuration has been loaded: %s\n",new Date());  

    }  

  

}  

这里使用的是:

[java] view
plain copy

 print?





thread1.join(3000);  

这句话的意思是,只要满足下面2个条件中的一个时,主线程就会继续执行thread.join()后面的代码:

条件1:thread1 执行完毕;

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

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

[java] view
plain copy

 print?





Beginning data sources loading: Fri Nov 14 14:35:45 CST 2014  

Main: Configuration has been loaded: Fri Nov 14 14:35:48 CST 2014  

Data sources loading has finished: Fri Nov 14 14:35:49 CST 2014  

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

例3:

[java] view
plain copy

 print?





package com.example;  

  

import java.util.Date;  

import java.util.concurrent.TimeUnit;  

  

public class DataSourcesLoader implements Runnable{  

  

    @Override  

    public void run() {  

        System.out.printf("Beginning data sources loading: %s\n",new Date());  

        try {  

          TimeUnit.SECONDS.sleep(4);  

        } catch (InterruptedException e) {  

          e.printStackTrace();  

        }  

        System.out.printf("Data sources loading has finished: %s\n",new Date());  

    }  

  

}  

[java] view
plain copy

 print?





package com.example;  

  

import java.util.Date;  

import java.util.concurrent.TimeUnit;  

  

public class NetworkConnectionsLoader implements Runnable{  

  

    @Override  

    public void run() {  

        System.out.printf("Beginning network connect loading: %s\n",new Date());  

        try {  

          TimeUnit.SECONDS.sleep(6);  

        } catch (InterruptedException e) {  

          e.printStackTrace();  

        }  

        System.out.printf("Network connect loading has finished: %s\n",new Date());  

          

    }  

      

    public static void main(String[] args){  

        DataSourcesLoader dsLoader = new DataSourcesLoader();  

        Thread thread1 = new Thread(dsLoader,"DataSourceThread");  

          

        NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();  

        Thread thread2 = new Thread(ncLoader,"NetworkConnectionLoader");  

          

        thread1.start();  

        thread2.start();   

          

        try {  

            thread1.join();  

            thread2.join(1900);  

          } catch (InterruptedException e) {  

            e.printStackTrace();  

          }  

            

          System.out.printf("Main: Configuration has been loaded: %s\n",new Date());  

    }  

  

}  

执行结果:

[java] view
plain copy

 print?





Beginning data sources loading: Fri Nov 14 14:39:20 CST 2014  

Beginning network connect loading: Fri Nov 14 14:39:20 CST 2014  

Data sources loading has finished: Fri Nov 14 14:39:24 CST 2014  

Main: Configuration has been loaded: Fri Nov 14 14:39:26 CST 2014  

Network connect loading has finished: Fri Nov 14 14:39:26 CST 2014  

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

[java] view
plain copy

 print?





thread2.join(3000);  

结果会和上面的一样吗?

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

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

[java] view
plain copy

 print?





Beginning data sources loading: Fri Nov 14 14:41:21 CST 2014  

Beginning network connect loading: Fri Nov 14 14:41:21 CST 2014  

Data sources loading has finished: Fri Nov 14 14:41:25 CST 2014  

Network connect loading has finished: Fri Nov 14 14:41:27 CST 2014  

Main: Configuration has been loaded: Fri Nov 14 14:41:27 CST 2014</span>  

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

PS:代码部分截取来自《Java 7 Concurrency Cookbook》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: