JAVA體系的線程的實現,線程的調度,狀態的轉換
java體系中線程的實現
1.使用內核線程實現
內核線程就是直接由操作系統內核支持的線程,這種線程由內核來完成線程切換,內核通過操作調度器對線程進行調度,並負責將線程的任務映射到各個處理器上,每個內核線程可以視作內核的一個分身,這樣操作系統就有能力處理多件事情,支持多線程的內核就叫做多線程內核,程序一般不會其使用內核線程,而是去使用內核線程的一種高級接口:輕量級進程,輕量級進程就是我們通常意義上的線程,由於每個輕量級進程都有一個內核線程支持,因此只有先支持內核線程,才能有輕量級進程(1:1關系),由於內核線程的支持,每個輕量級進程都成為一個獨立的調度單元,即使有一個輕量級進程在系統中阻塞了,也不會影響整個進程的工作,但是輕量級進程有局限性:1.由於是基於內核線程實現的,所以線程的各種操作(創建,析構,同步)都需要進行系統調用,而系統調用的代價高,需要在用戶態和內核態中來回切換,2.每個輕量級進程都需要一個內核線程的支持,因此輕量級進程要消耗一定的內核資源,因此系統支持的輕量級進程是有數量限制的
2.使用用戶線程實現
完全建立在用戶空間的線程庫上的線程,系統內核不能感知線程的存在,用戶線程的建立,同步,銷毀和調度完全在用戶態中實現,如果程序實現得當,這種線程不需要切換到內核態,操作可以快速和低消耗,可以支持規模更大的線程數量,部分高性能數據庫中的多線程就是由用戶線程實現的,但是由於不用切換到內核態,所以一些問題得不到內核的幫助,比如阻塞任何處理,多處理器系統中任何將線程映射到其他處理器上,這些問題解決起來異常困難
3.使用用戶線程加輕量級進程混合實現
即存在用戶線程,又存在輕量級進程,用戶線程還是完全建立在用戶空間當中,用戶線程的創建,切換,析構等操作依然廉價,並可以支持大規模的用戶線程並發,而操作系統提供的輕量級進程則作為用戶線程和內核之間的橋梁,這樣可以使用內核提供的線程調度功能和處理器映射,並且用戶線程的1系統調用要通過輕量級進程來完成,大大降低了整個經湊被完全阻塞的風險
java體系中線程的調度
主要有兩種調度方式:協同式線程調度,搶占式線程調度
1.協同式線程調度:線程的執行時間由自身控制,線程把工作執行完之後,通知系統切換到另一個線程上,協同式調度最大的好處就是實現簡單,而且由於線程要把自己的事情幹完才會進行線程切換,切換線程對自己也是可知的,所以不存在線程同步的問題,壞處就是線程執行時間不可控,甚至如果一個線程編寫有問題,一直不告訴系統進行線程切換,那麽程序就會阻塞
2.搶占式線程調度:每個線程將由系統來分配執行時間,線程的切換不由線程本身來決定,線程執行時間可控,不會有一個線程導致整個進程阻塞問題
“建議給某些線程多分配點時間”就引出了線程優先級的概念,優先級越高的線程越容易被系統選擇執行
雖然很多操作系統都有線程的優先級,但是這些優先級不一定可以與java中的線程優先級一一對應!
java體系中線程的狀態
java定義了5種線程狀態,一個線程在任意一個時間點只能有其中一種狀態!
1)新建:創建後尚未啟動的線程
2)運行:包括操作系統中的正在運行和就緒兩種狀態,也就是處於此狀態的線程可能正在運行或者等待cpu分配時間
3)等待:
*無限期等待:處於這種狀態的線程不會被cpu分配執行時間,他們要等待被其他線程喚醒
*限期等待:處於這種狀態的線程也不會被cpu分配執行時間,不過無需等待其他線程喚醒,在一定時間後可以由系統喚醒
4)阻塞:阻塞狀態在等待獲取一個排他鎖
5)結束:已終止線程的線程狀態
JAVA體系的線程的實現,線程的調度,狀態的轉換