Thread.join()方法解析

    xiaoxiao2021-03-25  124

    个人理解:

    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》

    转载请注明原文地址: https://ju.6miu.com/read-24294.html

    最新回复(0)