在 Java 開發中,多線程是實現高併發、提升程序執行效率的關鍵技術。本文系統梳理線程基礎概念、創建方式、生命週期狀態、線程安全問題及同步解決方案,並以單例模式雙重檢查鎖為例展示實戰應用。
new Thread() 或子類實例化run() 方法sleep()、wait() 狀態run() 執行完成或異常終止class PrintNum extends Thread {
public void run() {
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public PrintNum(String name) { super(name); }
}
public class TestThread {
public static void main(String[] args) {
PrintNum p1 = new PrintNum("線程1");
PrintNum p2 = new PrintNum("線程2");
p1.setPriority(Thread.MAX_PRIORITY);
p2.setPriority(Thread.MIN_PRIORITY);
p1.start(); p2.start();
}
}
三步驟:創建線程 → 重寫 run() → 調用 start() 啟動。
class SubThread implements Runnable {
public void run() {
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
public class TestThread {
public static void main(String[] args) {
SubThread s = new SubThread();
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.setName("線程1"); t2.setName("線程2");
t1.start(); t2.start();
}
}
| 維度 | 繼承 Thread | 實現 Runnable |
|---|---|---|
| 適用場景 | 無父類繼承、簡邏輯 | 需共享數據、避免單繼承限制 |
| 數據共享 | 每個線程獨有數據 | 同一 Runnable 實例天然共享 |
| 匿名內部類 | 適合一次性任務 | 同樣支援 |
class TicketSeller implements Runnable {
private int tickets = 100;
public void run() {
while (true) {
if (tickets > 0) {
// 模擬網絡延遲暴露問題
try { Thread.sleep(3); } catch (Exception e) {}
System.out.println(Thread.currentThread().getName() + " 第" + tickets-- + "票");
}
}
}
}
兩個窗口可能賣出同一張票(如第 0 張),因「檢查-執行」非原子操作。
核心原理:鎖機制,同一時間只允許一線程進入同步區。
synchronized (鎖對象) {
// 共享資源操作
}
鎖可為任意對象,建議用共享資源本身或 new Object()。
public synchronized void sell() { ... }
this類名.classclass Singleton {
private static volatile Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 第一次檢查,避免不必要同步
synchronized (Singleton.class) { // 類級別鎖
if (instance == null) { // 第二次檢查,確保單例
instance = new Singleton();
}
}
}
return instance;
}
}
關鍵點:
volatile 禁止指令重排,保證可見性Singleton.classRunnable + 線程池,解耦任務與執行java.util.concurrent 並發包(ReentrantLock、AtomicInteger、ConcurrentHashMap)