<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>
"); //-->

博客專(zhuān)欄

EEPW首頁(yè) > 博客 > Java 線(xiàn)程和操作系統的線(xiàn)程有啥區別?

Java 線(xiàn)程和操作系統的線(xiàn)程有啥區別?

發(fā)布人:編碼之外 時(shí)間:2021-04-23 來(lái)源:工程師 發(fā)布文章

想看解釋的小伙伴可直接翻到文末尋找答案。

1. 用戶(hù)空間和內核空間

關(guān)于內核態(tài)和用戶(hù)態(tài)我們在 了解操作系統的那些事兒,從這篇文章開(kāi)始 這篇文章中已經(jīng)詳細介紹過(guò),這里不再過(guò)多贅述。

至于什么是系統空間和用戶(hù)空間也非常好理解:在操作系統中,內存通常會(huì )被分成用戶(hù)空間(User space)與內核空間(Kernel space)這兩個(gè)部分。當進(jìn)程/線(xiàn)程運行在用戶(hù)空間時(shí)就處于用戶(hù)態(tài),運行在內核空間時(shí)就處于內核態(tài):

  • 運行在內核態(tài)的程序可以訪(fǎng)問(wèn)用戶(hù)空間和內核空間,或者說(shuō)它可以訪(fǎng)問(wèn)計算機的任何資源,不受限制,為所欲為,例如協(xié)調 CPU 資源,分配內存資源,提供穩定的環(huán)境供應用程序運行等
  • 而應用程序基本都是運行在用戶(hù)態(tài)的,或者說(shuō)用戶(hù)態(tài)就是提供應用程序運行的空間。運行在用戶(hù)態(tài)的程序只能訪(fǎng)問(wèn)用戶(hù)空間

那為什么要區分用戶(hù)態(tài)和內核態(tài)呢?

其實(shí)早期操作系統是不區分用戶(hù)態(tài)和內核態(tài)的,也就是說(shuō)應用程序可以訪(fǎng)問(wèn)任意內存空間,如果程序不穩定常常會(huì )讓系統崩潰,比如清除了操作系統的內存數據。為此大佬們設計出了一套規則:對于那些比較危險的操作需要切到內核態(tài)才能運行,比如 CPU、內存、設備等資源管理器程序就應該在內核態(tài)運行,否則安全性沒(méi)有保證。

舉個(gè)例子,對于文件系統和數據來(lái)說(shuō),文件系統數據和管理就必須放在內核態(tài),但是用戶(hù)的數據和管理可以放在用戶(hù)態(tài)。

用戶(hù)態(tài)的程序不能隨意操作內核地址空間,這樣有效地防止了操作系統程序受到應用程序的侵害。

那如果處于用戶(hù)態(tài)的程序想要訪(fǎng)問(wèn)內核空間的話(huà)怎么辦呢?就需要進(jìn)行系統調用從用戶(hù)態(tài)切換到內核態(tài)。

2. 操作系統線(xiàn)程① 在用戶(hù)空間中實(shí)現線(xiàn)程

早期的操作系統中,所有的線(xiàn)程都是在用戶(hù)空間下實(shí)現的,操作系統只能看到線(xiàn)程所屬的進(jìn)程,而不能看到線(xiàn)程。

image.png

從我們開(kāi)發(fā)者的角度來(lái)理解用戶(hù)級線(xiàn)程就是說(shuō):在這種模型下,我們需要自己定義線(xiàn)程的數據結構、創(chuàng )建、銷(xiāo)毀、調度和維護等,這些線(xiàn)程運行在操作系統的某個(gè)進(jìn)程內,然后操作系統直接對進(jìn)程進(jìn)行調度。

這種方式的好處一目了然,首先第一點(diǎn),就是即使操作系統原生不支持線(xiàn)程,我們也可以通過(guò)庫函數來(lái)支持線(xiàn)程;第二點(diǎn),線(xiàn)程的調度只發(fā)生在用戶(hù)態(tài),避免了操作系統從內核態(tài)到用戶(hù)態(tài)的轉換開(kāi)銷(xiāo)。

當然缺點(diǎn)也很明顯:由于操作系統看不見(jiàn)線(xiàn)程,不知道線(xiàn)程的存在,而 CPU 的時(shí)間片切換是以進(jìn)程為維度的,所以如果進(jìn)程中某個(gè)線(xiàn)程進(jìn)行了耗時(shí)比較長(cháng)的操作,那么由于用戶(hù)空間中沒(méi)有時(shí)鐘中斷機制,就會(huì )導致此進(jìn)程中的其它線(xiàn)程因為得不到 CPU 資源而長(cháng)時(shí)間的持續等待;另外,如果某個(gè)線(xiàn)程進(jìn)行系統調用時(shí)比如缺頁(yè)中斷而導致了線(xiàn)程阻塞,此時(shí)操作系統也會(huì )阻塞住整個(gè)進(jìn)程,即使這個(gè)進(jìn)程中其它線(xiàn)程還在工作。

② 在內核空間中實(shí)現線(xiàn)程

所謂內核級線(xiàn)程就是運行在內核空間的線(xiàn)程, 直接由內核負責,只能由內核來(lái)完成線(xiàn)程的調度。

幾乎所有的現代操作系統,包括 Windows、Linux、Mac OS X 和 Solaris 等,都支持內核線(xiàn)程。

每個(gè)內核線(xiàn)程可以視為內核的一個(gè)分身,這樣操作系統就有能力同時(shí)處理多件事情,支持多線(xiàn)程的內核就叫做多線(xiàn)程內核(Multi-Threads Kernel)。

從我們開(kāi)發(fā)者的角度來(lái)理解內核級線(xiàn)程就是說(shuō):我們可以直接使用操作系統中已經(jīng)內置好的線(xiàn)程,線(xiàn)程的創(chuàng )建、銷(xiāo)毀、調度和維護等,都是直接由操作系統的內核來(lái)實(shí)現,我們只需要使用系統調用就好了,不需要像用戶(hù)級線(xiàn)程那樣自己設計線(xiàn)程調度等。

image.png

上圖畫(huà)的是 1:1 的線(xiàn)程模型,所謂線(xiàn)程模型,也就是用戶(hù)線(xiàn)程和內核線(xiàn)程之間的關(guān)聯(lián)方式,線(xiàn)程模型當然不止 1:1 這一種,下面我們來(lái)詳細解釋以下這三種多線(xiàn)程模型:

下文翻譯自 https://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/4_Threads.html

1)多對一線(xiàn)程模型

image.png

  • 在多對一模型中,多個(gè)用戶(hù)級線(xiàn)程映射到某一個(gè)內核線(xiàn)程上
  • 線(xiàn)程管理由用戶(hù)空間中的線(xiàn)程庫處理,這非常有效
  • 但是,如果進(jìn)行了阻塞系統調用,那么即使其他用戶(hù)線(xiàn)程能夠繼續,整個(gè)進(jìn)程也會(huì )阻塞
  • 由于單個(gè)內核線(xiàn)程只能在單個(gè) CPU 上運行,因此多對一模型不允許在多個(gè) CPU 之間拆分單個(gè)進(jìn)程

從并發(fā)性角度來(lái)總結下,雖然多對一模型允許開(kāi)發(fā)人員創(chuàng )建任意多的用戶(hù)線(xiàn)程,但是由于內核只能一次調度一個(gè)線(xiàn)程,所以并未增加并發(fā)性?,F在已經(jīng)幾乎沒(méi)有操作系統來(lái)使用這個(gè)模型了,因為它無(wú)法利用多個(gè)處理核。

2)一對一線(xiàn)程模型

image.png

  • 一對一模型克服了多對一模型的問(wèn)題
  • 一對一模型創(chuàng )建一個(gè)單獨的內核線(xiàn)程來(lái)處理每個(gè)用戶(hù)線(xiàn)程
  • 但是,管理一對一模型的開(kāi)銷(xiāo)更大,涉及更多開(kāi)銷(xiāo)和減慢系統速度
  • 此模型的大多數實(shí)現都限制了可以創(chuàng )建的線(xiàn)程數

從并發(fā)性角度來(lái)總結下,雖然一對一模型提供了更大的并發(fā)性,但是開(kāi)發(fā)人員應注意不要在應用程序內創(chuàng )建太多線(xiàn)程(有時(shí)系統可能會(huì )限制創(chuàng )建線(xiàn)程的數量),因為管理一對一模型的開(kāi)銷(xiāo)更大。Windows (從 Win95 開(kāi)始) 和 Linux 都實(shí)現了線(xiàn)程的一對一模型。

3)多對多線(xiàn)程模型

image.png

  • 多對多模型將任意數量的用戶(hù)線(xiàn)程復用到相同或更少數量的內核線(xiàn)程上,結合了一對一和多對一模型的最佳特性
  • 用戶(hù)對創(chuàng )建的線(xiàn)程數沒(méi)有限制
  • 阻止內核系統調用不會(huì )阻止整個(gè)進(jìn)程
  • 進(jìn)程可以分布在多個(gè)處理器上
  • 可以為各個(gè)進(jìn)程分配可變數量的內核線(xiàn)程,具體取決于存在的 CPU 數量和其他因素
3. Java 線(xiàn)程

在進(jìn)入 Java 線(xiàn)程主題之前,有必要講解一下線(xiàn)程庫 Thread library 的概念。

在上面的模型介紹中,我們提到了通過(guò)線(xiàn)程庫來(lái)創(chuàng )建、管理線(xiàn)程,那么什么是線(xiàn)程庫呢?

線(xiàn)程庫就是為開(kāi)發(fā)人員提供創(chuàng )建和管理線(xiàn)程的一套 API。

當然,線(xiàn)程庫不僅可以在用戶(hù)空間中實(shí)現,還可以在內核空間中實(shí)現。前者涉及僅在用戶(hù)空間內實(shí)現的 API 函數,沒(méi)有內核支持。后者涉及系統調用,也就是說(shuō)調用庫中的一個(gè) API 函數將會(huì )導致對內核的系統調用,并且需要具有線(xiàn)程庫支持的內核。

下面簡(jiǎn)單介紹下三個(gè)主要的線(xiàn)程庫:

1)POSIX Pthreads:可以作為用戶(hù)或內核庫提供,作為 POSIX 標準的擴展

2)Win32 線(xiàn)程:用于 Window 操作系統的內核級線(xiàn)程庫

3)Java 線(xiàn)程:Java 線(xiàn)程 API 通常采用宿主系統的線(xiàn)程庫來(lái)實(shí)現,也就是說(shuō)在 Win 系統上,Java 線(xiàn)程 API 通常采用 Win API 來(lái)實(shí)現,在 UNIX 類(lèi)系統上,采用 Pthread 來(lái)實(shí)現。

下面我們來(lái)詳細講解 Java 線(xiàn)程:

事實(shí)上,在 JDK 1.2 之前,Java 線(xiàn)程是基于稱(chēng)為 "綠色線(xiàn)程"(Green Threads)的用戶(hù)級線(xiàn)程實(shí)現的,也就是說(shuō)程序員大佬們?yōu)?JVM 開(kāi)發(fā)了自己的一套線(xiàn)程庫或者說(shuō)線(xiàn)程管理機制。

在 JDK 1.2 及以后,JVM 選擇了更加穩定且方便使用的操作系統原生的內核級線(xiàn)程,通過(guò)系統調用,將線(xiàn)程的調度交給了操作系統內核。而對于不同的操作系統來(lái)說(shuō),它們本身的設計思路基本上是完全不一樣的,因此它們各自對于線(xiàn)程的設計也存在種種差異,所以 JVM 中明確聲明了:虛擬機中的線(xiàn)程狀態(tài),不反應任何操作系統中的線(xiàn)程狀態(tài)。

也就是說(shuō),在 JDK 1.2 及之后的版本中,Java 的線(xiàn)程很大程度上依賴(lài)于操作系統采用什么樣的線(xiàn)程模型,這點(diǎn)在不同的平臺上沒(méi)有辦法達成一致,JVM 規范中也并未限定 Java 線(xiàn)程需要使用哪種線(xiàn)程模型來(lái)實(shí)現,可能是一對一,也可能是多對多或多對一。

總結來(lái)說(shuō),回答下文題,現今 Java 中線(xiàn)程的本質(zhì),其實(shí)就是操作系統中的線(xiàn)程,其線(xiàn)程庫和線(xiàn)程模型很大程度上依賴(lài)于操作系統(宿主系統)的具體實(shí)現,比如在 Windows 中 Java 就是基于 Wind32 線(xiàn)程庫來(lái)管理線(xiàn)程,且 Windows 采用的是一對一的線(xiàn)程模型。


*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。



關(guān)鍵詞: JAVA

相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>