Linux從內核2.6開始使用NPTL (Native POSIX Thread Library)支持,但這時線程本質上仍是輕量級進程(LWP)。
Java裏的線程是由JVM來管理的,它如何對應到操做系統的線程是由JVM的實現來肯定的。Linux 2.6上的HotSpot使用了NPTL機制,JVM線程跟內核輕量級進程有一一對應的關係。線程的調度徹底交給了操做系統內核,固然jvm還保留一些策略足以影響到其內部的線程調度,舉個例子,在linux下,只要一個Thread.run就會調用一個fork產生一個線程。java
Java線程在Windows及Linux平臺上的實現方式,如今看來,是內核線程的實現方式。這種方式實現的線程,是直接由操做系統內核支持的——由內核完成線程切換,內核經過操縱調度器(Thread Scheduler)實現線程調度,並將線程任務反映到各個處理器上。內核線程是內核的一個分身。程序通常不直接使用該內核線程,而是使用其高級接口,即輕量級進程(LWP),也即線程。這看起來可能很拗口。看圖:linux
(說明:KLT即內核線程Kernel Thread,是「內核分身」。每個KLT對應到進程P中的某一個輕量級進程LWP(也即線程),期間要通過用戶態、內核態的切換,並在Thread Scheduler 下反應處處理器CPU上。)jvm
這種線程實現的方式也有它的缺陷:在程序面上使用內核線程,必然在操做系統上屢次來回切換用戶態及內核態;另外,由於是一對一的線程模型,LWP的支持數是有限的。工具
Runtime.getRuntime().availableProcessors();性能
因此最小線程數量即時cpu內核數量。若是全部的任務都是計算密集型的,這個最小線程數量就是咱們須要的線程數。開闢更多的線程只會影響程序的性能,由於線程之間的切換工做,會消耗額外的資源。若是任務是IO密集型的任務,咱們能夠開闢更多的線程執行任務。當一個任務執行IO操做的時候,線程將會被阻塞,處理器馬上會切換到另一個合適的線程去執行。若是咱們只擁有與內核數量同樣多的線程,即便咱們有任務要執行,他們也不能執行,由於處理器沒有能夠用來調度的線程。spa
若是線程有50%的時間被阻塞,線程的數量就應該是內核數量的2倍。若是更少的比例被阻塞,那麼它們就是計算密集型的,則須要開闢較少的線程。若是有更多的時間被阻塞,那麼就是IO密集型的程序,則能夠開闢更多的線程。因而咱們能夠獲得下面的線程數量計算公式:操作系統
線程數量=內核數量 / (1 - 阻塞率)線程
咱們能夠經過相應的分析工具或者java的management包來獲得阻塞率的數值。接口