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

Java 多線程創建的兩大核心路徑:繼承 Thread vs 實現 Runnable

     編輯:Java 相關知識

核心差異一覽

維度繼承 Thread 類實現 Runnable 接口
代碼存放位置子類 run() 方法實現類 run() 方法
繼承限制佔用單繼承名額無繼承限制,可繼承其他類
線程邏輯復用困難,邏輯綁定在線程類易復用,同一 Runnable 可交給多個 Thread
異常處理run() 可拋棄查異常run() 不可拋棄查異常,需內部 try-catch
推薦場景簡單測試、無邏輯復用需求企業級開發、線程池、任務解耦

方式一:繼承 Thread 類

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
        }
    }
}

public class Demo {
    public static void main(String[] args) {
        new MyThread().start(); // 線程名:Thread-0
        new MyThread().start(); // 線程名:Thread-1
    }
}

缺點:每個線程對象 = 一個任務邏輯,無法共享任務實例;若需共享數據需額外傳遞參數。

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

class TicketSeller implements Runnable {
    private int tickets = 100;
    private final Object lock = new Object(); // 共享鎖

    @Override
    public void run() {
        while (true) {
            synchronized (lock) { // 必須用同一把鎖
                if (tickets > 0) {
                    try { Thread.sleep(10); } catch (InterruptedException ignored) {}
                    System.out.println(Thread.currentThread().getName() + " 賣出第 " + tickets-- + " 張票");
                } else {
                    break;
                }
            }
        }
    }
}

public class Demo {
    public static void main(String[] args) {
        TicketSeller task = new TicketSeller(); // 單一任務實例,數據共享
        new Thread(task, "窗口-A").start();
        new Thread(task, "窗口-B").start();
        new Thread(task, "窗口-C").start();
        new Thread(task, "窗口-D").start();
    }
}

優勢:任務與線程分離,同一任務實例可被多線程並發執行,天然支持共享數據(如賣票案例的 tickets)。

線程安全核心:synchronized 關鍵字

多線程訪問共享資源時,必須保證三要素:

  1. 多線程:至少兩個線程並發
  2. 共享鎖:同一個 Object 或 this / Class 對象
  3. 同步代碼塊:synchronized(lock) { 临界区 }

synchronized(this) 與 synchronized(lock) 的區別:前者鎖住當前實例,後者可自定義鎖對象,粒度更可控。

現代替代方案:ExecutorService 線程池

生產環境極少直接 new Thread(),推薦使用線程池:

ExecutorService pool = Executors.newFixedThreadPool(4);
Runnable task = () -> System.out.println(Thread.currentThread().getName() + " 執行任務");
for (int i = 0; i < 10; i++) pool.submit(task);
pool.shutdown();

優勢:線程復用、任務隊列、拒絕策略、可監控、避免 OOM。

總結

  • 首選 Runnable + 線程池:解耦任務邏輯,支持共享數據,適配現代並發框架。
  • 理解 Thread 繼承:僅用於極簡場景或教學演示。
  • 線程安全三板斧:多線程 + 共享鎖 + synchronized,缺一不可。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved