1. 程式人生 > >泥瓦匠聊併發程式設計:執行緒與多執行緒必知必會(基礎篇)

泥瓦匠聊併發程式設計:執行緒與多執行緒必知必會(基礎篇)

本文目錄

  • 執行緒與多執行緒
  • 執行緒的執行與建立
  • 執行緒的狀態

1 執行緒與多執行緒

執行緒是什麼? 執行緒(Thread)是一個物件(Object)。用來幹什麼?Java 執行緒(也稱 JVM 執行緒)是 Java 程序內允許多個同時進行的任務。該程序內併發的任務成為執行緒(Thread),一個程序裡至少一個執行緒。

Java 程式採用多執行緒方式來支援大量的併發請求處理,程式如果在多執行緒方式執行下,其複雜度遠高於單執行緒序列執行。那麼多執行緒:指的是這個程式(一個程序)執行時產生了不止一個執行緒。

為啥使用多執行緒?

  • 適合多核處理器。一個執行緒執行在一個處理器核心上,那麼多執行緒可以分配到多個處理器核心上,更好地利用多核處理器。
  • 防止阻塞。將資料一致性不強的操作使用多執行緒技術(或者訊息佇列)加快程式碼邏輯處理,縮短響應時間。

聊到多執行緒,多半會聊併發與並行,咋理解並區分這兩個的區別呢?

  • 類似單個 CPU ,通過 CPU 排程演算法等,處理多個任務的能力,叫併發
  • 類似多個 CPU ,同時並且處理相同多個任務的能力,叫做並行

2 執行緒的執行與建立

2.1 執行緒的建立

Java 建立執行緒物件有兩種方法:

  • 繼承 Thread 類建立執行緒物件
  • 實現 Runnable 介面類建立執行緒物件

新建 MyThread 物件,程式碼如下:

/**
 * 繼承 Thread 類建立執行緒物件
 * @author
Jeff Lee @ bysocket.com * @since 2018年01月27日21:03:02 */
public class MyThread extends Thread { @Override // 可以省略 public void run() { System.out.println("MyThread 的執行緒物件正在執行任務"); } public static void main(String[] args) { for (int i = 0; i < 10; i++) { MyThread thread = new
MyThread(); thread.start(); System.out.println("MyThread 的執行緒物件 " + thread.getId()); } } }

MyThread 類繼承了 Thread 物件,並重寫(Override)了 run 方法,實現執行緒裡面的邏輯。main 函式是使用 for 語句,迴圈建立了 10 個執行緒,呼叫 start 方法啟動執行緒,最後列印當前執行緒物件的 ID。

run 方法和 start 方法的區別是什麼呢? run 方法就是跑的意思,執行緒啟動後,會呼叫 run 方法。 start 方法就是啟動的意思,就是啟動新執行緒例項。啟動執行緒後,才會調執行緒的 run 方法。

執行 main 方法後,控制檯列印如下:

MyThread 的執行緒物件正在執行任務
MyThread 的執行緒物件 10
MyThread 的執行緒物件正在執行任務
MyThread 的執行緒物件 11
MyThread 的執行緒物件正在執行任務
MyThread 的執行緒物件 12
MyThread 的執行緒物件正在執行任務
MyThread 的執行緒物件 13
MyThread 的執行緒物件正在執行任務
MyThread 的執行緒物件 14
MyThread 的執行緒物件正在執行任務
MyThread 的執行緒物件 15
MyThread 的執行緒物件正在執行任務
MyThread 的執行緒物件 16
MyThread 的執行緒物件正在執行任務
MyThread 的執行緒物件 17
MyThread 的執行緒物件正在執行任務
MyThread 的執行緒物件 18
MyThread 的執行緒物件正在執行任務
MyThread 的執行緒物件 19

可見,執行緒的 ID 是執行緒唯一識別符號,每個執行緒 ID 都是不一樣的。

start 方法和 run 方法的關係如圖所示: 

同理,實現 Runnable 介面類建立執行緒物件也很簡單,只是不同的形式。新建 MyThreadBrother 程式碼如下:

/**
 * 實現 Runnable 介面類建立執行緒物件
 * @author Jeff Lee @ bysocket.com
 * @since 2018年01月27日21:22:57
 */
public class MyThreadBrother implements Runnable {

    @Override // 可以省略
    public void run() {
        System.out.println("MyThreadBrother 的執行緒物件正在執行任務");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(new MyThreadBrother());
            thread.start();

            System.out.println("MyThreadBrother 的執行緒物件 " + thread.getId());
        }
    }
}

2.1 執行緒的執行

在執行上面兩個小 demo 後,JVM 執行了 main 函式執行緒,然後在主執行緒中執行建立了新的執行緒。正常情況下,所有執行緒執行到執行結束為止。除非某個執行緒中呼叫了 System.exit(1) 則被終止。

在實際開發中,一個請求到響應式是一個執行緒。但在這個執行緒中可以使用執行緒池建立新的執行緒,去執行任務。

3 執行緒的狀態

新建 MyThreadInfo 類,列印執行緒物件屬性,程式碼如下:

/**
 * 執行緒例項物件的屬性值
 * @author Jeff Lee @ bysocket.com
 * @since 2018年01月27日21:24:40
 */
public class MyThreadInfo extends Thread {

    @Override // 可以省略
    public void run() {
        System.out.println("MyThreadInfo 的執行緒例項正在執行任務");
//        System.exit(1);
    }

    public static void main(String[] args) {
        MyThreadInfo thread = new MyThreadInfo();
        thread.start();

        System.out.print("MyThreadInfo 的執行緒物件 \n"
                + "執行緒唯一識別符號:" + thread.getId() + "\n"
                + "執行緒名稱:" + thread.getName() + "\n"
                + "執行緒狀態:" + thread.getState() + "\n"
                + "執行緒優先順序:" + thread.getPriority());
    }
}

執行程式碼列印如下:

MyThreadInfo 的執行緒例項正在執行任務
MyThreadInfo 的執行緒物件 
執行緒唯一識別符號:10
執行緒名稱:Thread-0
執行緒狀態:NEW
執行緒優先順序:5

執行緒是一個物件,它有唯一識別符號 ID、名稱、狀態、優先順序等屬性。執行緒只能修改其優先順序和名稱等屬性 ,無法修改 ID 、狀態。ID 是 JVM 分配的,名字預設也為 Thread-XX,XX是一組數字。執行緒初始狀態為 NEW。

執行緒優先順序的範圍是 1 到 10 ,其中 1 是最低優先順序,10 是最高優先順序。不推薦改變執行緒的優先順序,如果業務需要,自然可以修改執行緒優先順序到最高,或者最低。

執行緒的狀態實現通過 Thread.State 常量類實現,有 6 種執行緒狀態:new(新建)、runnnable(可執行)、blocked(阻塞)、waiting(等待)、time waiting (定時等待)和 terminated(終止)。狀態轉換圖如下:

執行緒狀態流程大致如下:

  • 執行緒建立後,進入 new 狀態
  • 呼叫 start 或者 run 方法,進入 runnable 狀態
  • JVM 按照執行緒優先順序及時間分片等執行 runnable 狀態的執行緒。開始執行時,進入 running 狀態
  • 如果執行緒執行 sleep、wait、join,或者進入 IO 阻塞等。進入 wait 或者 blocked 狀態
  • 執行緒執行完畢後,執行緒被執行緒佇列移除。最後為 terminated 狀態。

4 小結

本文介紹了執行緒與多執行緒的基礎篇,包括了執行緒啟動及執行緒狀態等。下一篇我們聊下執行緒的具體操作。包括中斷、終止等

參考: 《Java併發程式設計的藝術》 《Java 7 併發程式設計實戰手冊》 《圖解 Java 多執行緒設計模式》