首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 多線程程式設計完整指南:生命週期、優先級、三種建立方式、Thread 方法與最佳實務

     編輯:Java 程式設計入門

Java 多線程程式設計完整指南

Java 內建支援多線程,一個多線程程式包含兩個以上可並發執行的部分,每部分稱為一個線程,定義獨立執行路徑。多線程是多任務的特殊形式,資源開銷較小,能充分利用 CPU 效能。


線程與進程關係

  • 進程:作業系統分配記憶體空間,包含一或多個線程
  • 線程:無法獨立存在,必須屬於某進程;進程持續執行直到所有非守護線程結束

線程生命週期五大狀態

線程生命週期圖

狀態說明
新建new Thread() 建立物件,尚未呼叫 start()
就緒呼叫 start() 後進入就緒佇列,等待 JVM 排程器調度
執行獲得 CPU 資源,執行 run();可轉為阻塞、就緒或死亡
阻塞執行 sleep()、wait()、同步鎖失敗、I/O 請求等;條件滿足後回就緒
死亡run() 完成或異常終止

阻塞細分:等待阻塞(wait())、同步阻塞(synchronized 鎖失敗)、其他阻塞(sleep()、join()、I/O)。


線程優先級

  • 範圍:1(MIN_PRIORITY)~ 10(MAX_PRIORITY),預設 5(NORM_PRIORITY)
  • 高優先級線程較易獲得 CPU,但不保證執行順序,高度平台相依

三種建立線程方式

1. 實作 Runnable 介面(推薦)

class RunnableDemo implements Runnable {
    private Thread t; private String threadName;
    RunnableDemo(String name) { threadName = name; System.out.println("Creating " + threadName); }
    public void run() {
        System.out.println("Running " + threadName);
        try { for (int i=4; i>0; i--) { System.out.println("Thread: " + threadName + ", " + i); Thread.sleep(50); } }
        catch (InterruptedException e) { System.out.println("Thread " + threadName + " interrupted."); }
        System.out.println("Thread " + threadName + " exiting.");
    }
    public void start() { if (t==null) { t = new Thread(this, threadName); t.start(); } }
}

public class TestThread {
    public static void main(String[] args) {
        new RunnableDemo("Thread-1").start();
        new RunnableDemo("Thread-2").start();
    }
}

2. 繼承 Thread 類別

class ThreadDemo extends Thread {
    // 結構類似 RunnableDemo,但繼承 Thread
    // 本質上仍是實作 Runnable
}

3. Callable + Future(可回傳值)

public class CallableThreadTest implements Callable<Integer> {
    public static void main(String[] args) {
        CallableThreadTest ctt = new CallableThreadTest();
        FutureTask<Integer> ft = new FutureTask<>(ctt);
        for (int i=0; i<100; i++) {
            System.out.println(Thread.currentThread().getName() + " 的迴圈變數 i=" + i);
            if (i==20) new Thread(ft, "有回傳值的線程").start();
        }
        try { System.out.println("子線程回傳值:" + ft.get()); }
        catch (Exception e) { e.printStackTrace(); }
    }
    @Override public Integer call() throws Exception {
        int i=0; for (; i<100; i++) System.out.println(Thread.currentThread().getName() + " " + i);
        return i;
    }
}

Thread 類別重要方法

方法說明
start()啟動線程,JVM 呼叫 run()
run()線程執行主體
setName(String)設定線程名稱
setPriority(int)設定優先級
setDaemon(boolean)標記守護/用戶線程
join(long ms)等待線程終止(最長 ms 毫秒)
interrupt()中斷線程
isAlive()檢測是否存活

靜態方法:yield()、sleep(ms)、holdsLock(obj)、currentThread()、dumpStack()。


三種建立方式比較

  • Runnable/Callable:線程類別可繼承其他類別,彈性較高
  • 繼承 Thread:寫法簡單,this 即為目前線程,無需呼叫 Thread.currentThread()

多線程核心概念

  • 線程同步
  • 線程間通訊
  • 線程死鎖
  • 線程控制:掛起、停止、恢復

多線程使用原則

  • 理解程式是並發而非串行執行
  • 善用多線程可寫出高效程式
  • 避免建立過多線程:上下文切換開銷會超過執行效能增益
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved