在高速發展的網際網路時代,企業紛紛將業務與產品部署至線上平台。支撐這些功能豐富、安全可靠的網頁應用背後,是 Java 這門與平台無關、功能強大的程式設計語言。Java 由 Sun Microsystems 開發,具備簡單性、物件導向、分散式、解釋執行、健壯性、安全性、架構中立、可移植、高效能、多線程、動態等核心特性。自問世以來,Java 憑藉編程簡單、代碼高效、可移植性強等優勢,迅速贏得開發者青睞,成為 Internet 上具革命性的語言,賦予 Web 動畫、多媒體與互動能力,開啟全新網頁時代。
Java 與 C++ 語法相似,可創建安全、可移植、多線程的互動式程式。其「一次編寫,到處執行」的跨平台特性,使後台開發成為高效實用的編程模式。使用者在螢幕前看到的圖形、計算結果,實際上由作業系統在後台調度事件、管理程式流向、處理堆疊、線程資源分配與記憶體管理等核心任務。本文將聚焦於多線程機制進行深入探討。
Java 內建的多線程功能允許單一程式同時執行多個子任務。線程(Thread)又稱輕量級進程,是進程內獨立執行的單元。相較於 C/C++,Java 的多線程實現更健壯,帶來更優的互動效能與即時控制能力(雖即時性仍受底層作業系統影響)。傳統單線程環境中,程式同一時間只能處理一個任務序列;而多線程環境如同辦公室職員同時處理多項工作:當某任務阻塞(如等待輸入),CPU 迅速切換至其他線程,透過時間片輪轉讓使用者感覺任務並行執行。
任何執行環境(單/多線程)皆包含三個關鍵面向:
在多線程編程中,每條線程擁有專屬的程式碼與資料,多線程可共享同一程式碼操作不同資料(如會計處理多部門帳目,邏輯相同但資料不同),亦可共享部分資料(如公司總帳匯總各部門資料)。此模型隱藏了 CPU 任務切換的複雜性,讓開發者彷彿擁有多個虛擬 CPU。
在 Java 中建立線程需三要素:執行代碼、操作資料、虛擬 CPU(封裝於 Thread 類實例)。採用 Runnable 介面可將代碼與資料封裝於類實例中:
public class SimpleRunnable implements Runnable {
private String message;
public static void main(String[] args) {
SimpleRunnable r1 = new SimpleRunnable("Hello");
Thread t1 = new Thread(r1);
t1.start();
}
public SimpleRunnable(String message) { this.message = message; }
public void run() {
for (;;) { System.out.println(message); }
}
}
線程啟動後在 public void run() 方法中執行,此為線程入口點。main() 建立 SimpleRunnable 實例,其成員變數 message 即為線程操作的資料,run() 方法為執行代碼。
線程擁有四種狀態:New(新建)、Running(執行)、Waiting(等待)、Done(結束)。新建線程處於 New 狀態,調用 start() 進入 Running;執行完畢或調用 stop() 進入 Done。Running 狀態下,CPU 以時間片輪轉執行多線程。阻塞操作(sleep()、suspend()、資源等待)將線程移入 Waiting,可透過 resume()、notify() 回到 Running。下表總結常用狀態轉換方法:
| 方法 | 描述 | 來源狀態 | 目標狀態 |
|---|---|---|---|
| start() | 啟動線程 | New | Running |
| stop() | 終止線程 | New/Running | Done |
| sleep(long) | 暫停指定毫秒 | Running | Waiting |
| suspend() | 掛起執行 | Running | Waiting |
| resume() | 恢復執行 | Waiting | Running |
| yield() | 主動放棄 CPU | Running | Running |
線程執行順序與時間片分配主要取決於開發者設定與作業系統排程策略。Java 虛擬機採用搶佔式排程:優先級最高的線程獲 CPU 執行權。Thread.NORM_PRIORITY 為預設優先級,可透過 setPriority() / getPriority() 調整(範圍 MIN_PRIORITY 至 MAX_PRIORITY)。若兩線程優先級相同,執行順序視作業系統時間片機制而定。對於大量線程管理,Java 提供線程組(ThreadGroup),可批量掛起、停止整組線程,簡化管理。
為防止多線程並發存取共享資源導致資料不一致,引入互斥鎖(Mutex)機制。讀寫鎖模式允許多人同時讀取,但寫入時必須獨佔。Semaphore 類實現此邏輯:
class Semaphore {
final static int EMPTY=0, READING=1, WRITING=2;
protected int state=EMPTY, readCnt=0;
public synchronized void readLock() { /* 實現讀鎖邏輯 */ }
public synchronized void writeLock() { /* 實現寫鎖邏輯 */ }
public synchronized void readUnlock() { /* 釋放讀鎖 */ }
public synchronized void writeUnlock() { /* 釋放寫鎖 */ }
}
測試程式顯示:多讀線程可並行,寫線程獨佔,確保資料完整性。
當兩線程互相持有對方所需鎖且均不釋放時發生死鎖。避免原則:
優點:功能完備、提升互動與即時效能、開發難度相對單線程較低。
缺點:早期版本未充分利用作業系統原生線程,導致跨平台行為差異(如 Windows vs. Unix 排程不同),增加開發者困擾。期待未來版本深度整合 OS 線程模型。