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

Java 多線程編程實戰:從 Thread/Runnable 到同步機制全景圖

     編輯:Java 程式設計入門

為什麼需要多線程?

單線程程序中,四個無關任務(打印、文件操作、數據庫訪問、繪圖)串行等待,資源利用率極低。多線程讓任務並發執行,如同現實中「寫信時讓兒子去買郵票」。

進程 vs 線程

  • 進程:重量級,獨立內存空間,通信困難,創建銷毀開銷大
  • 線程 (LWP):輕量級,共享進程內存,通信自然,創建銷毀廉價,Java 語言級原生支持

兩種實現線程的方式

方式一:繼承 Thread 類,重寫 run()

public class TimePrinter extends Thread {
    private int pauseTime;
    private String name;

    public TimePrinter(int pauseTime, String name) {
        this.pauseTime = pauseTime;
        this.name = name;
    }

    @Override
    public void run() {
        while (true) {
            try {
                System.out.println(name + ": " + new Date());
                Thread.sleep(pauseTime);
            } catch (Exception e) { e.printStackTrace(); }
        }
    }

    public static void main(String[] args) {
        new TimePrinter(1000, "Fast Guy").start();
        new TimePrinter(3000, "Slow Guy").start();
        // main 線程繼續運行...
    }
}

缺點:Java 單繼承限制,若類已繼承 Applet 等則無法使用。

方式二:實現 Runnable 接口(推薦)

public class TimePrinter implements Runnable {
    // 構造器、字段同前...
    @Override public void run() { /* 同前 */ }

    public static void main(String[] args) {
        new Thread(new TimePrinter(1000, "Fast Guy")).start();
        new Thread(new TimePrinter(3000, "Slow Guy")).start();
    }
}

優勢:不強加類層次,同一 Runnable 實例可被多個 Thread 包裝,靈活構建線程池等模式。

線程生命周期四態

  1. 新建:new Thread(),未 start()
  2. 可運行:就緒佇列中等待 CPU 時間片
  3. 阻塞:睡眠、等待 I/O、嘗試獲取鎖
  4. 死亡:run() 正常返回;不推薦 stop()(拋異常)、destroy()(強制終止不釋放鎖)

線程優先級

  • 範圍:1 (MIN_PRIORITY) ~ 10 (MAX_PRIORITY),默認 5 (NORM_PRIORITY)
  • 高優先級獲得 CPU 機會更大,非獨佔;getPriority()/setPriority() 動態調整

同步機制:synchronized 關鍵字

1. 同步方法

public synchronized void accessVal(int newVal) { /* 訪問共享變量 */ }
  • 每個對象實例一把鎖(this)
  • 同步方法執行前必須獲取鎖,返回時釋放
  • 靜態同步方法鎖定 Class 對象

2. 同步塊(細粒度控制)

synchronized (syncObject) { // 只鎖住關鍵代碼段
    // 訪問共享變量
}
  • syncObject 可為任意對象,通常用 this 或共享數據對象
  • 避免將大方法(如 run())整體同步導致並發度崩潰

最佳實踐總結

  • 優先 Runnable + 線程池 (ExecutorService) 管理線程生命周期
  • 共享可變狀態最小化,优先用 ThreadLocal、不可變對象、並發集合 (java.util.concurrent)
  • 同步塊比同步方法粒度更細,性能更優
  • 避免在同步塊中調用耗時操作(I/O、睡眠)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved