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

Java 線程創建與守護線程完整指南

     編輯:Java 相關知識

Java 線程創建的兩種核心方式

在 Java 並發編程中,線程創建是基礎中的基礎。主要有兩種實現路徑:實現 Runnable 接口與繼承 Thread 類。兩者各有優劣,選型需視業務場景而定。

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

此方式符合「組合優於繼承」的設計原則,支援多實現,便於資源共享。

public class RocketCountdown implements Runnable {
    private int countDown = 10;

    @Override
    public void run() {
        while (countDown-- > 0) {
            System.out.println("#" + Thread.currentThread().getName() + "(" + countDown + ")");
        }
    }

    public static void main(String[] args) {
        RocketCountdown task = new RocketCountdown();
        new Thread(task, "Thread-A").start();
        new Thread(task, "Thread-B").start();
        System.out.println("火箭發射倒計時:");
    }
}

關鍵點:同一 Runnable 實例可被多個線程共享,適合「多線程賣同一張票」等資源競爭場景。

方式二:繼承 Thread 類

代碼稍顯簡潔,獲取當前線程可直接用 this,但受限於單繼承,擴展性較弱。

public class SimpleCountdown extends Thread {
    private int countDown = 10;

    @Override
    public void run() {
        while (countDown-- > 0) {
            System.out.println("#" + this.getName() + "(" + countDown + ")");
        }
    }

    public static void main(String[] args) {
        new SimpleCountdown().start();
        new SimpleCountdown().start();
        System.out.println("火箭發射倒計時:");
    }
}

深度對比:如何選型?

維度RunnableThread 繼承
資源共享天然支援,同一任務實例可被多線程執行每個線程獨立實例,共享需額外處理
繼承限制無,可繼承其他業務類佔用繼承名額,無法再繼承父類
獲取當前線程需 Thread.currentThread()直接用 this
設計模式策略模式,任務與執行分離模板方法模式,耦合度較高

最佳實踐:優先選 Runnable(或 Callable),配合線程池使用,符合「任務與執行分離」的現代並發設計哲學。

守護線程:JVM 的隱形服務者

守護線程(Daemon Thread)是為非守護線程提供後台服務的線程(如 GC、JIT 編譯)。當所有用戶線程結束,JVM 會立即終止,不等待守護線程,且不執行其 finally 塊。

創建與驗證

public class DaemonDemo implements Runnable {
    @Override
    public void run() {
        try {
            while (true) {
                Thread.sleep(1000);
                System.out.println("#" + Thread.currentThread().getName() + " 心跳");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            System.out.println("finally 不會被執行"); // 驗證點
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 3; i++) {
            Thread t = new Thread(new DaemonDemo(), "Daemon-" + i);
            t.setDaemon(true); // 必須在 start() 前設置
            t.start();
        }
        System.out.println("主線程結束,JVM 即將退出");
        Thread.sleep(1500); // 給守護線程一點喘息時間
    }
}

輸出特徵:主線程結束後,守護線程瞬間消失,finally 無輸出,證明 JVM 強制終止。

守護線程鐵律

  • setDaemon(true) 必須在 start() 前調用,否則拋 IllegalThreadStateException。
  • 守護線程創建的子線程默認也是守護線程。
  • 避免在守護線程中持有需優雅關閉的資源(數據庫連接、文件句柄),改用 ShutdownHook 或非守護線程管理。

總結

掌握線程創建的兩種範式與守護線程特性,是寫出高併發、穩健 Java 程式的基石。實戰中:任務用 Runnable,執行交線程池,後台服務用守護線程但謹慎處理資源釋放。

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