1. 程式人生 > >join() 和 sleep() 區別

join() 和 sleep() 區別

err DC 實驗 rgs java tar 驗證 on() 對象鎖

來源於《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)方法具有釋放鎖的特點

join() 和 sleep() 區別