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

Java 進程與線程實現機制深度解析:從 JVM 到作業系統層面

     編輯:Java 相關知識

概述

進程與線程是作業系統的調度單位,可視為系統「資源」。Java 作為跨平台語言,透過 Process 與 Thread 類封裝底層功能。本文深入探討 Java 如何建立進程/線程、JVM 如何實現這些封裝、以及 Java 封裝與原生 OS 機制的異同與限制。

Java 進程建立與實現

核心類別

  • java.lang.Process:抽象類
  • ProcessImpl:JDK 內部實現類
  • ProcessBuilder(JDK 1.5+):提供更靈活的進程配置(環境變數、工作目錄、流合併)

兩種建立方式

// Runtime.exec 多重載形式
Process exec(String command)
Process exec(String[] cmdArray, String[] envp, File dir)

// ProcessBuilder 鏈式配置
Process p = new ProcessBuilder("cmd", "arg1").start();
ProcessBuilder pb = new ProcessBuilder("cmd", "arg1");
pb.environment().put("VAR", "value");
pb.directory(new File("/workdir"));
Process p = pb.start();

ProcessBuilder 最大優勢在於可預先配置屬性並複用,修改屬性僅影響後續建立的進程。

JVM 底層實現(以 Windows 為例)

ProcessImpl 透過 native 方法呼叫 Windows API:

JDK Native 方法Windows API
createCreateProcess, CreatePipe
closeCloseHandle
waitForWaitForMultipleObjects
destroyTerminateProcess
exitValueGetExitCodeProcess

以 create 為例,JVM 建立管道、轉換參數格式、呼叫 CreateProcess、取得進程句柄並返回。JVM 盡可能封裝平台細節,體現跨平台特性。

Java 進程與 OS 進程的差異

  • Java 隱藏了 PID 等平台資訊,僅能透過物件引用操作,引用丟失即無法控制
  • 輸入/輸出管道容量有限,未及時讀取易導致阻塞或死鎖
  • 執行 Windows 內建命令需透過 cmd.exe
  • Shell 管道(|)與重定向(>)無法直接透過參數傳遞,需在 Java 代碼中處理流

Java 線程建立與實現

兩種建立方式

// 繼承 Thread
class MyThread extends Thread {
    public void run() { System.out.println("Started"); }
}
new MyThread().start();

// 實作 Runnable
class MyRunnable implements Runnable {
    public void run() { System.out.println("Running"); }
}
new Thread(new MyRunnable()).start();

本質上皆是實作 run() 方法作為線程入口。

JVM 線程啟動流程

  1. Thread.start() 呼叫 native start0()
  2. Thread.registerNatives() 註冊本地方法(靜態區塊自動執行)
  3. JVM JVM_StartThread 建立平台原生線程,線程函數為 thread_entry
  4. thread_entry 透過 JNI 呼叫 Java 線程的 run() 方法
// 關鍵調用鏈
Thread.start() → start0() → JVM_StartThread() → thread_entry() → run()

直接呼叫 run() 不會建立新線程,僅在當前線程執行。

Java 線程與 OS 線程的對應關係

一對一模型:每個 Java 線程對應一個原生線程。但 Java 封裝帶來限制:

  • 無返回值:無法獲取線程退出碼(OS 儲存在 TCB 中)
  • 同步機制受限:join() 僅支援等待單一線程,無法實現「任一線程結束」或「所有線程結束」等複雜同步
  • 線程 ID 無關聯:Thread.getId() 返回內部計數器,與 OS 線程 ID 無關
  • 無 CPU 時間統計:無法精確獲取線程實際佔用 CPU 時間

總結

Java 封裝降低了開發複雜度,提升效率,但也屏蔽了 OS 原生特性,導致上述限制。隨著 Java 演進,封裝功能子集將更加完善,開發者需理解底層機制以避免潛在陷阱。

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