使用內核線程實現的方式也被稱為1:1實現。內核線程(Kernel-Level Thread,KLT)就是直接由操作系統內核(Kernel,下稱內核)支持的線程,這種線程由內核來完成線程切換,內核通過操縱調度器(Scheduler)對線程進行調度,并負責將線程的任務映射到各個處理器上。每個內核線程可以視為內核的一個分身,這樣操作系統就有能力同時處理多件事情,支持多線程的內核就稱為多線程內核 (Multi-Threads Kernel)
程序一般不會直接使用內核線程,而是使用內核線程的一種高級接口——輕量級進程(Light Weight Process,LWP),輕量級進程就是我們通常意義上所講的線程,由于每個輕量級進程都由一個 內核線程支持,因此只有先支持內核線程,才能有輕量級進程。這種輕量級進程與內核線程之間1:1 的關系稱為一對一的線程模型

由于內核線程的支持,每個輕量級進程都成為一個獨立的調度單元,即使其中某一個輕量級進程 在系統調用中被阻塞了,也不會影響整個進程繼續工作。輕量級進程也具有它的局限性:首先,由于是基于內核線程實現的,所以各種線程操作,如創建、析構及同步,都需要進行系統調用。而系統調用的代價相對較高,需要在用戶態(User Mode)和內核態(Kernel Mode)中來回切換。其次,每個輕量級進程都需要有一個內核線程的支持,因此輕量級進程要消耗一定的內核資源(如內核線程的棧空間),因此一個系統支持輕量級進程的數量是有限的;
處理器要去執行線程A的程序代碼時,并不是僅有代碼程序就能跑得起來,程序是數據與代碼的 組合體,代碼執行時還必須要有上下文數據的支撐。而這里說的“上下文”,以程序員的角度來看,是 方法調用過程中的各種局部的變量與資源;以線程的角度來看,是方法的調用棧中存儲的各類信息; 而以操作系統和硬件的角度來看,則是存儲在內存、緩存和寄存器中的一個個具體數值。物理硬件的 各種存儲設備和寄存器是被操作系統內所有線程共享的資源,當中斷發生,從線程A切換到線程B去執 行之前,操作系統首先要把線程A的上下文數據妥善保管好,然后把寄存器、內存分頁等恢復到線程B 掛起時候的狀態,這樣線程B被重新激活后才能仿佛從來沒有被掛起過。這種保護和恢復現場的工 作,免不了涉及一系列數據在各種寄存器、緩存中的來回拷貝,當然不可能是一種輕量級的操作
#### 缺點
1:1的內核線程模型是如今Java虛擬 機線程實現的主流選擇,但是這種映射到操作系統上的線程天然的缺陷是切換、調度成本高昂,系統 能容納的線程數量也很有限。以前處理一個請求可以允許花費很長時間在單體應用中,具有這種線程 切換的成本也是無傷大雅的,但現在在每個請求本身的執行時間變得很短、數量變得很多的前提下, 用戶線程切換的開銷甚至可能會接近用于計算本身的開銷,這就會造成嚴重的浪費
```
內核線程的調度成本主要來自于用戶態與核心態之間的狀態轉換,而這兩種狀態轉換的開銷主要 來自于響應中斷、保護和恢復執行現場的成本
```
- 簡介
- 概述
- 進程vs線程
- 資源限制
- 有關并行的兩個定律
- 線程同步和阻塞
- 線程阻塞
- 線程的特性
- 守護線程
- 線程異常
- Thread
- 線程狀態
- 線程中斷
- wait¬ify
- suspend&resume
- join&yield
- notify¬ifyAll
- Thread.sleep
- 線程任務
- Runnable
- Callable
- Future模式
- FutureTask
- 線程實現方式
- 內核線程實現
- 用戶線程實現
- 混合實現
- Java線程的實現
- java與協程
- 纖程-Fiber
- 線程調度
- 多線程協作方式
- 阻塞
- 放棄
- 休眠
- 連接線程
- 線程估算公式
- 線程活躍性
- 死鎖
- 線程安全性
- 對象的發布與逸出
- 構造方法溢出
- 線程封閉
- 對象的可變性
- 原子性
- 原子操作
- CPU原子操作原理
- 總線鎖
- 緩存鎖
- JAVA如何實現原子操作
- long和double讀寫操作原子性
- Adder和Accumulator
- 線程性能
- 同步工具類
- 閉鎖
- CountDownLatch
- FutureTask
- 信號量
- 柵欄
- CyclicBarrier
- Exchanger
- 并發編程
- volatile
- synchronized
- 無鎖
- 偏向鎖
- 輕量級鎖
- 鎖的優缺點對比
- 鎖升級
- 鎖消除
- Monitor
- synchronized語法
- Mutex Lock
- synchronized實踐問題
- synchronized&ReentrantLock
- Lock
- ReentrantLock
- Condition
- 讀寫鎖
- ReadWriteLock
- StampedLock
- 線程池
- Executor
- ExecutorService
- Executors
- ThreadPoolExecutor
- RejectedExecutionHandler
- ThreadFactory
- 線程池大小公式
- 動態調整線程池大小
- Fork/Join框架
- ForkJoinPool
- CompletableFuture
- JUC并發工具包
- LockSupport
- 延時任務與周期任務
- Timer
- TimerTask
- 異構任務并行化
- CompletionService
- volatile和synchronized比較
- 鎖優化
- 鎖相關概念
- 悲觀鎖(排它鎖)
- 樂觀鎖
- 自旋鎖
- 樂觀鎖vs悲觀鎖
- JVM鎖優化-鎖消除
- ThreadLocal
- InheritableThreadLocal
- TransmittableThreadLocal
- ThreadLocalRandom
- 無鎖
- AtomicInteger
- Unsafe
- AtomicReference
- AtomicStampedReference
- AtomicIntegerArray
- AtomicIntegerFieldUpdater
- 無鎖Vector
- LongAdder
- LongAccumulator
- 常見鎖類型
- 悲觀鎖&獨占鎖
- 樂觀鎖
- 樂觀鎖vs悲觀鎖
- 自旋鎖vs適應性自旋鎖
- 公平鎖vs非公平鎖
- 可重入鎖vs非可重入鎖
- 獨享鎖vs共享鎖
- 互斥鎖
- CAS
- AQS介紹
- AQS深入剖析
- AQS框架
- AQS核心思想
- AQS數據結構
- 同步狀態State
- ReentrantLock vs AQS
- AQS與ReentrantLock的關聯
- ReentrantLock具體實現
- 線程加入等待隊列
- 等待隊列中線程出隊列時機
- 如何解鎖
- 中斷恢復后的執行流程
- ReentrantLock的可重入應用
- JUC中的應用場景
- 自定義同步工具
- CLH鎖
- 并發框架
- Akka
- Disruptor-無鎖緩存框架
- 常見面試題
- 兩個線程交替打印A和B
- 附錄