來源於《Java多線程編程核心技術》
一、join() 作用
在很多情況,主線程創建並啟動子線程,如果子線程中需要進行大量的耗時計算,主線程往往早於子線程結束。這時,如果主線程想等待子線程執行結束之后再結束,比如子線程處理一個數據,主線程要取得這個數據,就要用待jion() 方法。
方法join()的作用是等待線程對象的銷毀
二、區別
sleep(long)方法在睡眠時不釋放對象鎖
join(long)方法在等待的過程中釋放對象鎖
三、實例
創建join_sleep_1項目
類ThreadA.java代碼如下
1 package extthread; 2 3 public class ThreadA extends Thread { 4 5 private ThreadB b; 6 7 public ThreadA(ThreadB b) { 8 super(); 9 this.b = b; 10 } 11 12 @Override 13 public void run() { 14 try { 15 synchronized (b) { 16 b.start(); 17 Thread.sleep(6000); 18 } 19 } catch (InterruptedException e) { 20 e.printStackTrace(); 21 } 22 } 23 }
類ThreadB.java代碼如下
1 package extthread; 2 3 public class ThreadB extends Thread { 4 5 @Override 6 public void run() { 7 try { 8 System.out.println(" b run begin timer=" 9 + System.currentTimeMillis()); 10 Thread.sleep(5000); 11 System.out.println(" b run end timer=" 12 + System.currentTimeMillis()); 13 } catch (InterruptedException e) { 14 e.printStackTrace(); 15 } 16 } 17 18 synchronized public void bService() { 19 System.out.println("��ӡ��bService timer=" + System.currentTimeMillis()); 20 } 21 22 }
類ThreadC.java代碼如
1 package extthread; 2 3 public class ThreadC extends Thread { 4 5 private ThreadB threadB; 6 7 public ThreadC(ThreadB threadB) { 8 super(); 9 this.threadB = threadB; 10 } 11 12 @Override 13 public void run() { 14 threadB.bService(); 15 } 16 }
Run.java 代碼
1 package test.run; 2 3 import extthread.ThreadA; 4 import extthread.ThreadB; 5 import extthread.ThreadC; 6 7 public class Run { 8 public static void main(String[] args) { 9 10 try { 11 ThreadB b = new ThreadB(); 12 13 ThreadA a = new ThreadA(b); 14 a.start(); 15 16 Thread.sleep(1000); 17 18 ThreadC c = new ThreadC(b); 19 c.start(); 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } 23 } 24 }
結果
由於線程ThreadA使用Thread.sleep(long)方法一直持有ThreadB對象的鎖,時間達到6秒,所以線程C只有在ThreadA時間到達6秒后釋放ThreadB的鎖時,才可以調用ThreadB中的同步方法Synchronized public void bService()
上面實驗證明Thread.sleep(long)不釋放鎖
下面實驗修改ThreadA.java
1 package extthread; 2 3 public class ThreadA extends Thread { 4 5 private ThreadB b; 6 7 public ThreadA(ThreadB b) { 8 super(); 9 this.b = b; 10 } 11 12 @Override 13 public void run() { 14 try { 15 synchronized (b) { 16 b.start(); 17 b.join(); 18 for (int i = 0; i < Integer.MAX_VALUE; i++) { 19 String newString = new String(); 20 Math.random(); 21 } 22 } 23 } catch (InterruptedException e) { 24 e.printStackTrace(); 25 } 26 } 27 }
結果如下
由於線程ThreadA釋放了ThreadB的鎖,所以線程ThreadC可以調用ThreadB中的同步方法synchronized public void bService()
實驗證明join(long)方法具有釋放鎖的特點