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

Java 並發基石:進程與線程的由來、區別與多線程性能抉擇

     編輯:Java 程式設計入門

一、為什麼需要進程?

1.1 批處理時代的痛點

早期計算機單道批處理:用戶提交磁帶任務,CPU 執行一個,等待 I/O 時空閒,利用率極低。

1.2 多道程序與進程誕生

為提高 CPU 利用率,需要內存同時駐留多個程序。進程 應運而生,作為:

  • 資源分配基本單位:擁有獨立地址空間、文件句柄、信號量等
  • 調度基本單位(早期):保存運行狀態(PC、寄存器、堆棧),支持上下文切換
  • 隔離容器:進程間內存隔離,互不干擾

1.3 並發的本質

單核 CPU 通過時間片輪轉,宏觀上「同時」運行多任務,微觀上交替執行。

二、為什麼需要線程?

2.1 進程的局限

進程切換開銷大(內存映射、文件表、上下文)。進程內部只能串行執行,無法並行處理多個子任務(如 GUI 響應、網絡通信、計算)。

2.2 線程:輕量級調度單元

  • 共享進程資源:代碼段、堆、文件描述符、全局變量
  • 私有狀態:程序計數器、棧、局部變量、線程局部存儲 (TLS)
  • 調度基本單位:現代 OS 調度線程而非進程
  • 創建/切換開銷小:無需複製地址空間

2.3 線程實現模型

  • 用戶級線程 (ULT):用戶態管理,切換快但阻塞一個阻塞全進程
  • 內核級線程 (KLT):內核調度,阻塞不影響其他,切換需陷入內核
  • 混合模型 (M:N):多用戶線程映射多內核線程(如 Go 語言、早期 Java Green Threads)

Java 1.2+ 使用1:1 模型(每個 Java 線程映射一個內核線程),充分利用多核。

三、多線程並發核心挑戰:共享數據訪問

線程共享堆內存 → 多線程同時讀寫同一變量 → 競態條件 → 數據不一致。

// 經典非線程安全示例
class Counter { int count = 0; void inc() { count++; } }
// 兩線程並發調用 inc() 10000 次,結果往往 < 20000

解決方案:synchronized、Lock、AtomicInteger、ThreadLocal、無鎖算法等(後續文章詳述)。

四、多線程性能:並非銀彈

場景單核 CPU多核 CPU
CPU 密集型(計算、壓縮、加密)多線程降低性能(上下文切換開銷)多線程提升性能(並行利用多核)
I/O 密集型(網絡、磁盤、數據庫)多線程顯著提升(等待時切換執行其他)多線程提升(同步非阻塞/異步更優)
混合型視具體比例權衡線程池隔離不同任務類型

五、工程決策指南

  1. 默認單線程:簡單、可調試、無同步煩惱
  2. 引入多線程前:性能分析確認瓶頸、任務可並行化、收益>複雜度成本
  3. 使用線程池:ExecutorService 管理生命周期、復用線程、控制並發度
  4. 避免過早優化:先正確、再快;優先用高層並發工具(CompletableFuture、並發集合、並行流)

六、總結

  • 進程:資源隔離容器,讓 OS 並發成為可能
  • 線程:輕量調度單元,讓進程內部並發成為可能
  • 核心矛盾:共享數據訪問衝突 → 同步機制
  • 性能真相:視任務類型與硬件而定,非無條件提升
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved