來源於《Java多線程編程核心技術》java
在不少狀況,主線程建立並啓動子線程,若是子線程中須要進行大量的耗時計算,主線程每每早於子線程結束。這時,若是主線程想等待子線程執行結束以後再結束,好比子線程處理一個數據,主線程要取得這個數據,就要用待jion() 方法。編程
方法join()的做用是等待線程對象的銷燬多線程
sleep(long)方法在睡眠時不釋放對象鎖dom
join(long)方法在等待的過程當中釋放對象鎖ide
建立join_sleep_1項目this
類ThreadA.java代碼以下spa
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代碼如3d
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 代碼code
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)方法具備釋放鎖的特色