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

Java 多線程核心技術深度解析:創建、同步、通信與優化實戰

     編輯:Java 相關知識

線程與進程本質區別

  • 進程:資源分配基本單位,擁有獨立內存空間(代碼、數據、堆、棧)
  • 線程:CPU 調度基本單位,屬於進程,共享進程內存(堆、方法區),私有棧、程序計數器
  • 關係:一個進程至少一個線程(主線程),多線程實現併發執行

線程創建的三種方式

1. 實現 Runnable 接口(推薦)

public class MyTask implements Runnable {
    @Override
    public void run() {
        for (int i = 1; i <= 20; i++) {
            System.out.println("子線程: " + i);
        }
    }
}

// 使用
Thread thread = new Thread(new MyTask());
thread.start();  // 啟動線程,異步執行 run()

優點:避免單繼承限制、邏輯與控制分離、支持線程池復用

2. 繼承 Thread 類

public class MyThread extends Thread {
    @Override
    public void run() {
        // 線程邏輯
    }
}

// 使用
new MyThread().start();

3. 實現 Callable + FutureTask(有返回值)

Callable task = () -> {
    int sum = 0;
    for (int i = 1; i <= 100; i++) sum += i;
    return sum;
};
FutureTask futureTask = new FutureTask<>(task);
new Thread(futureTask).start();
Integer result = futureTask.get();  // 阻塞獲取結果

線程常用方法詳解

方法說明關鍵點
start()啟動線程異步調用 run(),不可重複調用
run()線程執行體直接調用為同步方法調用
sleep(ms)靜態方法,當前線程休眠不釋放鎖、拋出 InterruptedException
yield()靜態方法,讓出 CPU 時間片僅重新競爭,不保證切換
join()合併線程(等待結束)當前線程阻塞,直到目標線程結束
interrupt()中斷線程設置中斷標誌,不強制終止
isInterrupted()檢查中斷標誌不清除標誌
stop()強制終止(已棄用)不安全,導致數據不一致

優雅停止線程模式

錯誤方式

thread.stop();  // 棄用,不安全
thread.interrupt();  // 僅設置標誌,需配合邏輯判斷

正確方式:標誌位 + interrupt

public class GracefulStopTask implements Runnable {
    private volatile boolean running = true;  // volatile 保證可見性
    
    @Override
    public void run() {
        while (running && !Thread.currentThread().isInterrupted()) {
            try {
                System.out.println("工作中...");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // 睡眠中被中斷,標誌被清除,需重新設置或退出
                Thread.currentThread().interrupt(); // 重新設置標誌
                break;
            }
        }
        System.out.println("線程安全退出");
    }
    
    public void shutdown() {
        running = false;
    }
}

// 使用
GracefulStopTask task = new GracefulStopTask();
Thread thread = new Thread(task);
thread.start();
// ... 5秒後停止
Thread.sleep(5000);
task.shutdown();  // 設置標誌
thread.interrupt(); // 打斷可能的阻塞

線程同步機制

synchronized 關鍵字

// 同步方法
public synchronized void syncMethod() { ... }

// 同步塊(更精細控制)
public void syncBlock() {
    synchronized (this) {  // 或共享對象鎖
        // 臨界區代碼
    }
}

ReentrantLock 顯式鎖

private final ReentrantLock lock = new ReentrantLock();

public void lockMethod() {
    lock.lock();
    try {
        // 臨界區
    } finally {
        lock.unlock();  // 必須在 finally 中釋放
    }
}

優勢:可中斷、公平/非公平、條件變量、超時獲取

volatile 關鍵字

  • 保證可見性:寫入立即刷新主存,讀取從主存加載
  • 禁止指令重排序:內存屏障
  • 不保證原子性:複合操作仍需鎖

線程通信:wait/notify 機制

// 共享對象
final Object lock = new Object();
boolean ready = false;

// 生產者
synchronized (lock) {
    while (!ready) {
        lock.wait();  // 釋放鎖並等待
    }
    // 消費數據
}

// 消費者
synchronized (lock) {
    ready = true;
    lock.notifyAll();  // 唤醒所有等待線程
}

關鍵:wait()/notify() 必須在 synchronized 塊中調用,使用 while 而非 if 防止虛假喚醒。

線程優先級

// 優先級範圍 1-10,默認 5
thread.setPriority(Thread.MAX_PRIORITY);  // 10
thread.setPriority(Thread.MIN_PRIORITY);  // 1
thread.setPriority(Thread.NORM_PRIORITY); // 5

注意:優先級只是調度提示,不保證執行順序,受操作系統調度器影響大。

線程組與守護線程

// 守護線程:JVM 僅剩守護線程時退出
thread.setDaemon(true);  // 必須在 start() 前設置

// 線程組:批量管理
ThreadGroup group = new ThreadGroup("MyGroup");
new Thread(group, task).start();
group.interrupt();  // 批量中斷

現代併發工具類(JUC 包)

組件用途
ExecutorService線程池管理,替代手動創建線程
CompletableFuture異步編程、組合、異常處理
CountDownLatch倒計時同步器
CyclicBarrier循環柵欄,多線程彙聚
Semaphore信號量,資源訪問控制
ConcurrentHashMap高併發線程安全 Map
BlockingQueue阻塞隊列,生產消費模式
ThreadLocal線程局部變量,數據隔離

線程池核心參數

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    corePoolSize,      // 核心線程數
    maximumPoolSize,   // 最大線程數
    keepAliveTime,     // 非核心線程存活時間
    TimeUnit.SECONDS,  // 時間單位
    new LinkedBlockingQueue<>(), // 工作隊列
    new ThreadFactoryBuilder().setNameFormat("worker-%d").build(), // 線程工廠
    new ThreadPoolExecutor.AbortPolicy() // 拒絕策略
);

總結

Java 多線程是高併發系統的基石。掌握線程創建、生命周期控制、同步機制、通信模式、優雅停止、線程池配置與 JUC 組件應用,是構建穩定高效併發系統的必備技能。實戰中優先使用線程池、CompletableFuture、高級同步器,避免底層 API 直接操作帶來的風險。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved