1. 程式人生 > >Thread、執行緒建立、synchronized、執行緒生命週期

Thread、執行緒建立、synchronized、執行緒生命週期

程序:程序指正在執行的程式,當一個程式進入記憶體執行,即變成一個程序,程序是處於執行過程中的程式,並且具有一定獨立功能。

執行緒:執行緒是程序中的一個執行單元,負責當前程序中程式的執行,一個程序中至少有一個執行緒。

jvm啟動後,必然有一個執行路徑(執行緒)從main方法開始的,一直執行到main方法結束,這個執行緒在java中稱之為 主執行緒(main執行緒)。

程式執行原理:

?        分時排程

所有執行緒輪流使用 CPU 的使用權,平均分配每個執行緒佔用 CPU 的時間。PU(中央處理器)使用搶佔式排程模式在多個執行緒間進行著高速的切換

?        搶佔式排程

優先讓優先順序高的執行緒使用 CPU,如果執行緒的優先順序相同,那麼會隨機選擇一個(執行緒隨機性),Java使用的為搶佔式排程。

 

多執行緒程式並不能提高程式的執行速度,但能夠提高程式執行效率,讓CPU的使用率更高。

 

 

 

建立執行緒的第一種方式

 *

 *         1.定義一個類繼承Thread類

 *         2.重寫Thread類的run方法(執行緒中要執行的內容  執行緒任務)

 *         3.開啟執行緒

 *                 建立子類物件

 *                 呼叫繼承過來的start方法

方法:

 *                 start:開啟執行緒 執行run方法

 *                 run:直接呼叫run方法 程式還是一個單執行緒的程式

sleep:在指定的時間內叫程式休眠

 

呼叫run方法和呼叫start方法的區別:

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

 *

 *         Tread類的方法

 *                 String getName() 獲取執行緒名稱

 *                 static Thread currentThread()   返回對當前正在執行的執行緒物件的引用。

 *                 void setName(String name) 設定執行緒名稱

兩種構造方法

Thread()

    Thread(String name)

執行緒建立的第二種方式 實現Runnable介面

好處:實現介面把run方法和start分開<解耦> 重寫run方法是單獨的實現類Runnable裡面

 *

 *         1.定義一個類實現Runnable介面

 *         2.重寫run方法 (執行緒任務)

 *        3.開啟執行緒

 *                 建立實現類物件

 *                 建立Thread類物件 在構造方法中傳入Runnable的實現類物件

 *                 呼叫start方法

匿名內部類

 *         作用:建立一個類的子類物件的快捷方式

 *         new 父類/介面(){

 *          重寫方法

 

三種匿名內部類:

//定義一個類 繼承Thread類 建立這個類的物件

Thread t = new Thread(){

public void run(){

System.out.println("!!");

}

};

 

t.start();

//定義一個類 實現Runnable 建立實現類物件

Runnable r = new Runnable() {

@Override

public void run() {

System.out.println("###");

}

};

Thread t1 = new Thread(r);

t1.start();

//定義一個類實現Runnable介面建立Thread程序

new Thread(new Runnable() {

@Override

public void run() {

System.out.println("???");        

}

}).start();

 

 

繼承Thread和實現Runable的優缺點

    實現Runnable介面避免了單繼承的侷限性,所以較為常用。實現Runnable介面的方式,更加的符合面向物件,執行緒分為兩部分,一部分執行緒物件,一部分執行緒任務。

    第一種方式繼承Thread類,執行緒物件和執行緒任務耦合在一起。一旦建立Thread類的子類物件,既是執行緒物件,又有執行緒任務。

    實現runnable介面,將執行緒任務單獨分離出來封裝成物件,型別就是Runnable介面型別。Runnable介面對執行緒物件和執行緒任務進行解耦。

 

 

執行緒同步

    同步原理:有鎖的執行緒執行,沒鎖的執行緒等待

     * 同步程式碼塊

     *          synchronized(任意物件){

     *                  可能出現問題程式碼

     *         }

     *                 同步程式碼塊: 在程式碼塊宣告上 加上synchronized

        synchronized (鎖物件) {

          可能會產生執行緒安全問題的程式碼

        }

    同步程式碼塊中的鎖物件可以是任意的物件;

      但多個執行緒時,要使用同一個鎖物件才能夠保證執行緒安全。

 

     * 同步方法

    ?        同步方法:在方法宣告上加上synchronized

        public synchronized void method(){

                           可能會產生執行緒安全問題的程式碼

      }

        同步方法中的鎖物件是 this

   同步方法

       *  在方法的返回值前加上synchronized關鍵字

       *  同步方法有鎖嗎?有  鎖是誰?  鎖是this

       *  同步方法可以是靜態的嗎?  可以

       *  鎖還是this嗎? 絕對不是

       *  static後鎖是誰? 類名.class        

<在第一條執行緒搶的cup資源後執行程式碼等執行判斷是否有鎖有鎖則獲鎖進入程式碼塊開始執行執行緒執行完畢後出程式碼塊釋放鎖

      如果在程式碼塊中阻塞下一條執行緒獲得cpu資源到了程式碼塊沒鎖等待直到程式碼塊中有鎖的執行緒執行完畢釋放後獲得鎖才可以執行>

 

       *同步鎖:

          Lock提供了一個更加面對物件的鎖,在該鎖中提供了更多的操作鎖的功能。        

          JDK1.5 Lock介面

       * 子類

       *                 ReentrantLock 建立鎖使用

       * 方法

       *                  void lock() 獲取鎖

       *                  void unlock()  釋放鎖