| 維度 | 進程 | 線程 |
|---|---|---|
| 資源隔離 | 獨立代碼/數據空間 | 同類線程共享代碼/數據 |
| 獨有資源 | 完整地址空間 | 獨立棧幀 + PC 計數器 |
| 切換開銷 | 大(上下文切換) | 小(輕量級進程) |
| 關係 | 1 個進程包含 1~n 個線程 | 線程屬於某個進程 |
多進程 = OS 同時運行多程序;多線程 = 單程序內多執行流並行。
class MyThread extends Thread {
private final String name;
public MyThread(String name) { this.name = name; }
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + " 執行:" + i);
try { Thread.sleep((int)(Math.random() * 10)); }
catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
// 啟動
new MyThread("A").start();
new MyThread("B").start();
關鍵點:start() 啟動新線程異步執行 run();直接調用 run() 只會在主線程同步執行。同一 Thread 實例不可重複 start(),否則拋 IllegalThreadStateException。
class MyRunnable implements Runnable {
private final String name;
public MyRunnable(String name) { this.name = name; }
@Override
public void run() {
// 業務邏輯同 Thread 子類
}
}
// 啟動:包裝成 Thread
new Thread(new MyRunnable("C")).start();
new Thread(new MyRunnable("D")).start();
優勢:
Runnable 實例可被多線程共享 → 實現資源共享(如賣票系統共享餘票數)// Thread 子類:各實例獨有 count,無法共享
class Thread1 extends Thread { private int count = 5; ... }
// Runnable:共享同一實例 → 共享 count
class Thread2 implements Runnable {
private int count = 15;
public void run() { ... count-- ... }
}
Thread2 shared = new Thread2();
new Thread(shared, "C").start();
new Thread(shared, "D").start();
new Thread(shared, "E").start();
NEW --start()--> RUNNABLE <--running--> RUNNING
↑ ↑ ↑
| | | sleep/yield/wait/join/I/O
| | |
| +--notify/notifyAll/interrupt/timeout
|
+-- 获取 CPU 時間片
RUNNING --run() 結束/異常--> TERMINATED
五大標準狀態:NEW、RUNNABLE、RUNNING、BLOCKED(含 WAITING/TIMED_WAITING)、TERMINATED。
阻塞三類型:
wait() 進入等待池sleep()、join()、I/O 操作MIN=1、NORM=5、MAX=10Thread.sleep(ms)Object.wait()notify()/notifyAll() 喚醒Thread.yield()join()join() → 主線程阻塞,等待子線程終止notify()/notifyAll()suspend()/resume() 已棄用(死鎖風險)| 方法 | 所屬類 | 釋放鎖 | 狀態轉換 | 典型用途 |
|---|---|---|---|---|
| sleep() | Thread | 否 | RUNNING→TIMED_WAITING | 延遲、節流 |
| wait() | Object | 是 | RUNNING→WAITING | 線程協作 |
| yield() | Thread | 否 | RUNNING→RUNNABLE | 禮讓同優先級 |
| join() | Thread | 否 | RUNNING→WAITING | 等待線程結束 |
interrupt() 中斷拋 InterruptedException
public class PrintABC {
static class Printer implements Runnable {
private final String name;
private final Object prevLock, selfLock;
Printer(String name, Object prev, Object self) {
this.name = name; this.prevLock = prev; this.selfLock = self;
}
@Override public void run() {
for (int i = 0; i < 10; i++) {
synchronized (prevLock) {
synchronized (selfLock) {
System.out.print(name);
selfLock.notify(); // 喚醒下一個
}
try { prevLock.wait(); } // 等待上一個
catch (InterruptedException e) { break; }
}
}
}
}
public static void main(String[] args) throws Exception {
Object a = new Object(), b = new Object(), c = new Object();
new Thread(new Printer("A", c, a)).start();
Thread.sleep(100); // 確保啟動順序 A→B→C
new Thread(new Printer("B", a, b)).start();
Thread.sleep(100);
new Thread(new Printer("C", b, c)).start();
}
}
核心邏輯:每線程持有「前驅鎖」與「自我鎖」,雙重同步實現嚴格輪轉。notify() 釋放自我鎖喚醒下一個,wait() 釋放前驅鎖等待被喚醒。
main() 創建Thread.currentThread() 獲取setDaemon(true):設置守護線程(需在 start() 前)this,同一實例互斥Class 對象,類級別互斥synchronized(lockObj) { },自定義鎖粒度
// 1. 實例鎖:同步塊
synchronized(this) { ... }
// 2. 專用鎖對象(推薦):零長度 byte 数组最經濟
private final byte[] lock = new byte[0];
synchronized(lock) { ... }
// 3. 類鎖:靜態方法或 synchronized(Foo.class)
synchronized(Foo.class) { ... }
關鍵規則:
synchronized 不可繼承,子類需顯式加鎖System.identityHashCode() 排序)java.util.concurrent 高階組件
class MyThread extends Thread {
private final String data;
MyThread(String data) { this.data = data; }
public void run() { System.out.println(data); }
}
new MyThread("init-data").start();
class MyRunnable implements Runnable {
private String data;
public void setData(String data) { this.data = data; }
public void run() { System.out.println(data); }
}
MyRunnable r = new MyRunnable();
r.setData("dynamic");
new Thread(r).start();
interface Callback { void onResult(int sum); }
class Worker implements Runnable {
private final Callback cb;
Worker(Callback cb) { this.cb = cb; }
public void run() {
int n1 = new Random().nextInt(1000);
int n2 = new Random().nextInt(2000);
cb.onResult(n1 + n2); // 異步回調
}
}
new Thread(new Worker(sum -> System.out.println("Sum: " + sum))).start();
掌握上述核心知識體系,配合 java.util.concurrent 套件(線程池、鎖、並發集合、同步器)實戰演練,即可構建高性能、穩定的多線程應用。建議進階學習:AQS 原理、ThreadLocal 記憶體洩漏、CompletableFuture 異步編排、JVM 線程棧調優。