1. 程式人生 > >java 多執行緒程式設計之join()的用法

java 多執行緒程式設計之join()的用法

join的用法,先看幾個例子在說。

程式1:
public class ThreadTest implements Runnable {

 public static int a = 0;
 public synchronized void inc() {
  a++;
 }

 public void run() {
  for (int i = 0; i < 5; i++) {
   inc();
  }
 }

 public static void main(String[] args) throws Exception {


  Runnable r = new ThreadTest();
  Thread t1 = new Thread(r);
  t1.start();

  System.out.println(a);


 }
}

咋一看以為結果是:5  ,其實不然

程式2:在一基礎上新增點東西 System.out.println(a+",");


public class ThreadTest implements Runnable {

 public static int a = 0;
 public synchronized void inc() {
  a++;

System.out.println(a+",");
 }

 public void run() {
  for (int i = 0; i < 5; i++) {
   inc();
  }
 }

 public static void main(String[] args) throws Exception {


  Runnable r = new ThreadTest();
  Thread t1 = new Thread(r);
  t1.start();

  System.out.println(a);


 }
}

結果:

0

1,2,3,4,5,

說明a已經被加了5次。但有兩個問題

1)為什麼main方法中的列印語句還是0呢?

2)為什麼main方法中的列印語句先執行了呢?

程式3

public class ThreadTest implements Runnable {

 public static int a = 0;
 public synchronized void inc() {
  a++;
 }

 public void run() {
  for (int i = 0; i < 5; i++) {
   inc();
  }
 }

 public static void main(String[] args) throws Exception {


  Runnable r = new ThreadTest();
  Thread t1 = new Thread(r);
  t1.start();

   for (int i=0; i<300; i++) {
      System.out.print(i);
   }
   System.out.println();
   System.out.println(a);

 }
}

結果:

0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
5

此時的結果5正確了。說明執行緒在i迴圈100次後,全部都結束了。

之所以會產生1)2)原因是:由於有兩個執行緒,我們不知道主執行緒執行到什麼時候開始執行子執行緒,這是由於雖然你呼叫start方法但是呼叫該方法只是準備執行緒並不是馬上啟動.所以,當程式執行的時候,很隨機地執行這兩個執行緒中的一個,也就很隨機地執行System.out.println(a); 這個語句了.於是,有可能子執行緒只執行了1次a=+1這個語句,也可能是2次或者其它多少次,還可能是0次,所以列印的結果是個隨機數

程式4:在程式1的基礎上新增 t1.join(); 達到與程式3同樣的效果

public class ThreadTest implements Runnable {

 public static int a = 0;
 public synchronized void inc() {
  a++;
 }

 public void run() {
  for (int i = 0; i < 5; i++) {
   inc();
  }
 }

 public static void main(String[] args) throws Exception {


  Runnable r = new ThreadTest();
  Thread t1 = new Thread(r);
  t1.start();

   t1.join();
   System.out.println(a);

 }
}

結果:5

總結:join方法的功能就是使非同步執行的執行緒變成同步執行。也就是說,當呼叫執行緒例項的start方法後,這個方法會立即返回,如果在呼叫start方法後後需要使用一個由這個執行緒計算得到的值,就必須使用join方法。如果不使用join方法,就不能保證當執行到start方法後面的某條語句時,這個執行緒一定會執行完。而使用join方法後,直到這個執行緒退出,程式才會往下執行。