1. 程式人生 > 實用技巧 >執行緒&同步習題答案

執行緒&同步習題答案

基礎題

練習一:多執行緒開啟

問題:

請描述Thread類中的start()方法與run()方法的區別。

答:

執行緒物件呼叫run()方法不開啟執行緒,僅是物件呼叫方法。執行緒物件呼叫start()方法開啟執行緒,並讓jvm呼叫run()方法在開啟的執行緒中執行。

練習二:建立多執行緒

問題:

請描述建立執行緒的兩種方式。

答:

第一種方式是將類宣告為 Thread 的子類。

  1. 定義Thread類的子類,並重寫該類的run()方法,該run()方法的方法體就代表了執行緒需要完成的任務,因此把run()方法稱為執行緒執行體。
  2. 建立Thread子類的例項,即建立了執行緒物件。
  3. 呼叫執行緒物件的
    start()方法來啟動該執行緒。

第二種方式宣告一個類實現Runnable 介面。

1. 定義Runnable介面的實現類,並重寫該介面的run()方法,該run()方法的方法體同樣是該執行緒的執行緒執行體。

2. 建立Runnable實現類的例項,並以此例項作為Threadtarget來建立Thread物件,Thread物件才是真正的執行緒物件。

3. 呼叫執行緒物件的start()方法來啟動執行緒。

練習三:多執行緒練習

問題:

請編寫程式,分別列印主執行緒的名稱和子執行緒的名稱。

要求使用兩種方式實現:

第一種方式:繼承Thread類。

第二種方法:實現Runnable介面。

答:

操作步驟描述

第一種方式:繼承Thread

1.定義一個子執行緒的類,繼承Thread

2.在子執行緒類中重寫run方法,在run方法中列印子執行緒的名稱

3.定義一個測試類

4.main方法中列印主執行緒的名稱

5.main方法中建立子執行緒物件

6.呼叫子執行緒物件的start方法,開啟子執行緒

第二種方式:實現Runnable介面

1.定義一個子任務類,實現Runnable介面;

2.在子任務類中重寫run方法,在run方法中列印子執行緒的名稱;

3.定義一個測試類;

4.main方法中列印主執行緒的名稱;

5.main方法中建立一個子任務物件;

6.main方法中建立一個Thread類的物件,並把子任務物件傳遞給Thread類的構造方法;

7.呼叫Thread類物件的start方法開啟子執行緒;

操作步驟答案

l第一種方式:繼承Thread

/*
* 1.定義一個子執行緒的類,繼承Thread類;
*/

public class SubThread extends Thread {
 /*
  *2.在子執行緒類中重寫run方法,在run方法中列印子執行緒的名稱;
  */
 public void run() {
  // 列印子執行緒的名稱
  System.out.println("subThread:" + Thread.currentThread().getName());
 }
}

 

/*
* 3.定義一個測試類
*/

public class ThreadDemo {
 public static void main(String[] args) {
  // 4.在main方法中列印主執行緒的名稱;
  System.out.println("main:" + Thread.currentThread().getName());
  // 5.在main方法中建立子執行緒物件;
  SubThread st = new SubThread();
  // 6.呼叫子執行緒物件的start方法,開啟子執行緒。
  st.start();
 }
}

  

第二種方式:實現Runnable介面

/*
* 1.定義一個子任務類,實現Runnable介面。
*/

public class SubRunnable implements Runnable {
 @Override
 public void run() {
  // 2.在子任務類中重寫run方法,在run方法中列印子執行緒的名稱。
  System.out.println("SubRunnable:"+ Thread.currentThread().getName());
 }
}

/*
* 3.定義一個測試類。
*/

public class RunnableDemo {
 public static void main(String[] args) {
  // 4.在main方法中列印主執行緒的名稱。
  System.out.println("RunnableDemo:"+ Thread.currentThread().getName());
  // 5.在main方法中建立一個子任務物件。
  SubRunnable r = new SubRunnable();
  // 6.在main方法中建立一個Thread類的物件,並把子任務物件傳遞給Thread類的                         構造方法。
  Thread t = new Thread(r);
  // 7.呼叫Thread類物件的start方法開啟子執行緒。
  t.start();
 }
}

 

練習四:實現Runnable介面的優勢

問題:

請描述實現Runnable介面比繼承Thread類所具有的優勢:

答:

1. 適合多個相同的程式程式碼的執行緒去共享同一個資源。

2. 可以避免java中的單繼承的侷限性。

3. 增加程式的健壯性,實現解耦操作,程式碼可以被多個執行緒共享,程式碼和資料獨立。

4. 執行緒池只能放入實現Runablecallable類執行緒,不能直接放入繼承Thread的類。

練習五:執行緒狀態

問題:請描述線上程的生命週期中, 有幾種狀態呢?

答:

  1. NEW(新建) 執行緒剛被建立,但是並未啟動。
  2. Runnable(可執行)

執行緒可以在java虛擬機器中執行的狀態,可能正在執行自己程式碼,也可能沒有,這取決於作業系統處理器。

  1. Blocked(鎖阻塞)

當一個執行緒試圖獲取一個物件鎖,而該物件鎖被其他的執行緒持有,則該執行緒進入Blocked狀態;當該執行緒持有鎖時,該執行緒將變成Runnable狀態。

  1. Waiting(無限等待)

一個執行緒在等待另一個執行緒執行一個(喚醒)動作時,該執行緒進入Waiting狀態。進入這個狀態後是不能自動喚醒的,必須等待另一個執行緒呼叫notify或者notifyAll方法才能夠喚醒。

  1. Timed Waiting(計時等待)

waiting狀態,有幾個方法有超時引數,呼叫他們將進入Timed Waiting狀態。這一狀態將一直保持到超時期滿或者接收到喚醒通知。帶有超時引數的常用方法有Thread.sleep Object.wait

  1. Teminated(被終止)

因為run方法正常退出而死亡,或者因為沒有捕獲的異常終止了run方法而死亡。