java執行緒join方法使用方法簡介

  • 2019 年 10 月 7 日
  • 筆記

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/u014427391/article/details/101308043

本部落格簡介介紹一下java執行緒的join方法,join方法是實現執行緒同步,可以將原本並行執行的多執行緒方法變成串列執行的

如圖所示程式碼,是並行執行的

public class ThreadTest {      //private static final Long count = 10000L;      public static void main(String[] args){          long base = System.currentTimeMillis();          try {              ThreadJoin t1 = new ThreadJoin("執行緒1");              ThreadJoin t2 = new ThreadJoin("執行緒2");              //t1.join();              t1.start();              t1.join();              t2.start();            } catch (Exception e) {              e.printStackTrace();          }          long time = System.currentTimeMillis() - base;          System.out.println("執行時間:"+time);      }    }  class ThreadJoin extends Thread{      private static final Long count = 10L;        public ThreadJoin(String name){          super(name);      }        @Override      public void run() {          //super.run();          for(int i = 1; i <= count; i ++){              System.out.println(this.getName()+":"+i);          }      }  }

列印出來的資訊,都是這樣的

執行時間:0  執行緒1:1  執行緒2:1  執行緒2:2  執行緒2:3  執行緒2:4  執行緒2:5  執行緒2:6  執行緒2:7  執行緒2:8  執行緒2:9  執行緒2:10  執行緒1:2  執行緒1:3  執行緒1:4  執行緒1:5  執行緒1:6  執行緒1:7  執行緒1:8  執行緒1:9  執行緒1:10

要實現串列執行,可以加上join方法,實現執行緒1執行完成後才開始執行執行緒2,也就是串列執行

public class ThreadTest {      //private static final Long count = 10000L;      public static void main(String[] args){          long base = System.currentTimeMillis();          try {              ThreadJoin t1 = new ThreadJoin("執行緒1");              ThreadJoin t2 = new ThreadJoin("執行緒2");              //t1.join();              t1.start();              t1.join();              t2.start();            } catch (Exception e) {              e.printStackTrace();          }          long time = System.currentTimeMillis() - base;          System.out.println("執行時間:"+time);      }    }  class ThreadJoin extends Thread{      private static final Long count = 10L;        public ThreadJoin(String name){          super(name);      }        @Override      public void run() {          //super.run();          for(int i = 1; i <= count; i ++){              System.out.println(this.getName()+":"+i);          }      }  }
執行緒1:1  執行緒1:2  執行緒1:3  執行緒1:4  執行緒1:5  執行緒1:6  執行緒1:7  執行緒1:8  執行緒1:9  執行緒1:10  執行時間:0  執行緒2:1  執行緒2:2  執行緒2:3  執行緒2:4  執行緒2:5  執行緒2:6  執行緒2:7  執行緒2:8  執行緒2:9  執行緒2:10

從執行結果看,已經是串列執行執行緒

所以上面的例子是調了現場1的join方法,也就是說要先執行完成執行緒1,然後才執行main主執行緒

join方法的作用是,舉個例子,在A執行緒里調B執行緒的join方法時,要先B執行緒執行完成,然後才會繼續執行A執行緒

ok,上面調join方法是不加參數的,也可以加上參數,比如執行緒A.join(10);,就是說執行緒A執行10s後,繼續執行B執行緒

注意:join時間參數預設的情況,默認是0,也就是說join()等同於join(0);

/**       * Waits for this thread to die.       *       * <p> An invocation of this method behaves in exactly the same       * way as the invocation       *       * <blockquote>       * {@linkplain #join(long) join}{@code (0)}       * </blockquote>       *       * @throws  InterruptedException       *          if any thread has interrupted the current thread. The       *          <i>interrupted status</i> of the current thread is       *          cleared when this exception is thrown.       */      public final void join() throws InterruptedException {          join(0);      }

Thread類里的源碼,可以看出默認賦值為0,然後這個0是什麼意思?0不是表示執行0s,而是表示要A執行緒執行完成才繼續執行B執行緒的意思

ok,然後為什麼調用了join方法就可以實現執行緒同步?我們簡單看一下程式碼:

public final synchronized void join(long millis)      throws InterruptedException {          long base = System.currentTimeMillis();          long now = 0;  		//執行時間必須為正數          if (millis < 0) {              throw new IllegalArgumentException("timeout value is negative");          }  		//執行時間為0或者預設情況          if (millis == 0) {              while (isAlive()) {//表示執行緒還沒執行好                  wait(0);//調用執行緒的wait方法              }          } else {//執行時間大於0的情況              while (isAlive()) {                  long delay = millis - now;//循環計算延期時間                  if (delay <= 0) {                      break;                  }                  wait(delay);//同樣調用執行緒的wait方法                  now = System.currentTimeMillis() - base;              }          }      }

ok,看了一下源碼,還是比較容易理解的,其實就是調用了現場wait方法實現執行緒同步的

Tags: