欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java線程和操作系統(tǒng)線程的關(guān)系解讀

 更新時(shí)間:2023年06月12日 14:46:49   作者:CringKong  
這篇文章主要介紹了Java線程和操作系統(tǒng)線程的關(guān)系解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

1.操作系統(tǒng)線程模型

1.1 線程實(shí)現(xiàn)在用戶(hù)空間下

當(dāng)線程在用戶(hù)空間下實(shí)現(xiàn)時(shí),操作系統(tǒng)對(duì)線程的存在一無(wú)所知,操作系統(tǒng)只能看到進(jìn)程,而不能看到線程。所有的線程都是在用戶(hù)空間實(shí)現(xiàn)。

在操作系統(tǒng)看來(lái),每一個(gè)進(jìn)程只有一個(gè)線程。過(guò)去的操作系統(tǒng)大部分是這種實(shí)現(xiàn)方式,這種方式的好處之一就是即使操作系統(tǒng)不支持線程,也可以通過(guò)庫(kù)函數(shù)來(lái)支持線程。

我們換一種通俗的方式來(lái)講解這段話,首先就是在這在模型下,程序員需要自己實(shí)現(xiàn)線程的數(shù)據(jù)結(jié)構(gòu)、創(chuàng)建銷(xiāo)毀和調(diào)度維護(hù)。也就相當(dāng)于需要實(shí)現(xiàn)一個(gè)自己的線程調(diào)度內(nèi)核,而同時(shí)這些線程運(yùn)行在操作系統(tǒng)的一個(gè)進(jìn)程內(nèi),最后操作系統(tǒng)直接對(duì)進(jìn)程進(jìn)行調(diào)度。

這樣做有一些優(yōu)點(diǎn),首先就是確實(shí)在操作系統(tǒng)中實(shí)現(xiàn)了真實(shí)的多線程,其次就是線程的調(diào)度只是在用戶(hù)態(tài),減少了操作系統(tǒng)從內(nèi)核態(tài)到用戶(hù)態(tài)的切換開(kāi)銷(xiāo)。

當(dāng)然缺點(diǎn)也很明顯:

這種模式最致命的缺點(diǎn)也是由于操作系統(tǒng)不知道線程的存在,因此當(dāng)一個(gè)進(jìn)程中的某一個(gè)線程進(jìn)行系統(tǒng)調(diào)用時(shí),比如缺頁(yè)中斷而導(dǎo)致線程阻塞,此時(shí)操作系統(tǒng)會(huì)阻塞整個(gè)進(jìn)程,即使這個(gè)進(jìn)程中其它線程還在工作。

還有一個(gè)問(wèn)題是假如進(jìn)程中一個(gè)線程長(zhǎng)時(shí)間不釋放CPU,因?yàn)橛脩?hù)空間并沒(méi)有時(shí)鐘中斷機(jī)制,會(huì)導(dǎo)致此進(jìn)程中的其它線程得不到CPU而持續(xù)等待。

1.2 線程實(shí)現(xiàn)在操作系統(tǒng)內(nèi)核中

內(nèi)核線程就是直接由操作系統(tǒng)內(nèi)核(Kernel)支持的線程,這種線程由內(nèi)核來(lái)完成線程切換,內(nèi)核通過(guò)操縱調(diào)度器(Scheduler)對(duì)線程進(jìn)行調(diào)度,并負(fù)責(zé)將線程的任務(wù)映射到各個(gè)處理器上。

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

通俗的將就是,程序員直接使用操作系統(tǒng)中已經(jīng)實(shí)現(xiàn)的線程,而線程的創(chuàng)建、銷(xiāo)毀、調(diào)度和維護(hù),都是靠操作系統(tǒng)(準(zhǔn)確的說(shuō)是內(nèi)核)來(lái)實(shí)現(xiàn),程序員只需要使用系統(tǒng)調(diào)用,而不需要自己設(shè)計(jì)線程的調(diào)度算法和線程對(duì)CPU資源的搶占使用。

而不得提到的就是,Linux下的輕量級(jí)進(jìn)程,因?yàn)長(zhǎng)inux并不像Windows那樣,真正的實(shí)現(xiàn)了線程的數(shù)據(jù)結(jié)構(gòu),而是直接采用了和系統(tǒng)中進(jìn)程一樣的實(shí)現(xiàn)方式。

目前的Linux已經(jīng)基于NPTL實(shí)現(xiàn)了更符合POSIX標(biāo)準(zhǔn)的線程,之前我學(xué)習(xí)到的LinuxThreads早已經(jīng)被替代,這里為自己的不求甚解反省。

輕量級(jí)進(jìn)程(LWP)是建立在內(nèi)核之上并由內(nèi)核支持的用戶(hù)線程,它是內(nèi)核線程的高度抽象,每一個(gè)輕量級(jí)進(jìn)程都與一個(gè)特定的內(nèi)核線程關(guān)聯(lián)。內(nèi)核線程只能由內(nèi)核管理并像普通進(jìn)程一樣被調(diào)度。

Linux中程序一般不會(huì)直接去使用內(nèi)核線程,而是去使用內(nèi)核線程的一種高級(jí)接口–輕量級(jí)進(jìn)程,輕量級(jí)進(jìn)程就是我們通常意義上所講的線程,由于每個(gè)輕量級(jí)進(jìn)程都由一個(gè)內(nèi)核線程支持,因此只有先支持內(nèi)核線程,才能有輕量級(jí)進(jìn)程。 這種輕量級(jí)進(jìn)程與內(nèi)核線程之間1:1的關(guān)系稱(chēng)為一對(duì)一的線程模型。

這里要說(shuō)明的是,一對(duì)一的線程模型是一種概念,Linux是一對(duì)一的線程模型,上面的表述太繞了,現(xiàn)在的Linux中線程已經(jīng)的被更優(yōu)雅的實(shí)現(xiàn)了。

PS:其實(shí)Linux中的pthread庫(kù)就是調(diào)用了輕量級(jí)線程接口,來(lái)在操作系統(tǒng)中創(chuàng)建一個(gè)內(nèi)核線程。

Pthread庫(kù)目前也是基于NPTL實(shí)現(xiàn),已經(jīng)是一種符合POSIX標(biāo)準(zhǔn)的線程模型了,Linux擺脫了原來(lái)LWP的陰影。 

1.3使用用戶(hù)線程加輕量級(jí)進(jìn)程混合實(shí)現(xiàn)

在這種混合實(shí)現(xiàn)下,即存在用戶(hù)線程,也存在輕量級(jí)進(jìn)程。用戶(hù)線程還是完全建立在用戶(hù)空間中,因此用戶(hù)線程的創(chuàng)建、切換、析構(gòu)等操作依然廉價(jià),并且可以支持大規(guī)模的用戶(hù)線程并發(fā)。

而操作系統(tǒng)提供支持的輕量級(jí)進(jìn)程則作為用戶(hù)線程和內(nèi)核線程之間的橋梁,這樣可以使用內(nèi)核提供的線程調(diào)度功能及處理器映射,并且用戶(hù)線程的系統(tǒng)調(diào)用要通過(guò)輕量級(jí)進(jìn)程來(lái)完成,大大降低了整個(gè)進(jìn)程被完全阻塞的風(fēng)險(xiǎn)。

在這種混合模式中,用戶(hù)線程與輕量級(jí)進(jìn)程的數(shù)量比是不定的,即為N:M的關(guān)系:

明白了前面兩種模型,就應(yīng)該很好理解這種線程模型了,但實(shí)際上現(xiàn)在主流的操作系統(tǒng)已經(jīng)不太常用這種線程模型了。

2019.3.26更新:

目前來(lái)說(shuō),作為異步回調(diào)以外的另一種解決方案,這種m:n的線程模型可以說(shuō)大有可為,Golang的協(xié)程就是使用了這種模型,在用戶(hù)態(tài),協(xié)程能快速的切換,避免了線程調(diào)度的CPU開(kāi)銷(xiāo)問(wèn)題,協(xié)程相當(dāng)于線程的線程。

2.Java線程

2.1 Java線程在操作系統(tǒng)上本質(zhì)

Java線程在JDK1.2之前,是基于稱(chēng)為“綠色線程”(Green Threads)的用戶(hù)線程實(shí)現(xiàn)的,而在JDK1.2中,線程模型替換為基于操作系統(tǒng)原生線程模型來(lái)實(shí)現(xiàn)。

因此,在目前的JDK版本中,操作系統(tǒng)支持怎樣的線程模型,在很大程度上決定了Java虛擬機(jī)的線程是怎樣映射的,這點(diǎn)在不同的平臺(tái)上沒(méi)有辦法達(dá)成一致,虛擬機(jī)規(guī)范中也并未限定Java線程需要使用哪種線程模型來(lái)實(shí)現(xiàn)。

線程模型只對(duì)線程的并發(fā)規(guī)模和操作成本產(chǎn)生影響,對(duì)Java程序的編碼和運(yùn)行過(guò)程來(lái)說(shuō),這些差異都是透明的。

也就說(shuō)JDK1.2之前,

**程序員們?yōu)镴VM開(kāi)發(fā)了自己的一個(gè)線程調(diào)度內(nèi)核,而到操作系統(tǒng)層面就是用戶(hù)空間內(nèi)的線程實(shí)現(xiàn)。

**而到了JDK1.2及以后,JVM選擇了更加穩(wěn)健且方便使用的操作系統(tǒng)原生的線程模型,通過(guò)系統(tǒng)調(diào)用,將程序的線程交給了操作系統(tǒng)內(nèi)核進(jìn)行調(diào)度

對(duì)于Sun JDK來(lái)說(shuō),它的Windows版與Linux版都是使用一對(duì)一的線程模型實(shí)現(xiàn)的,一條Java線程就映射到一條輕量級(jí)進(jìn)程之中,因?yàn)閃indows和Linux系統(tǒng)提供的線程模型就是一對(duì)一的。

也就是說(shuō),現(xiàn)在的Java中線程的本質(zhì),其實(shí)就是操作系統(tǒng)中的線程,Linux下是基于pthread庫(kù)實(shí)現(xiàn)的輕量級(jí)進(jìn)程,Windows下是原生的系統(tǒng)Win32 API提供系統(tǒng)調(diào)用從而實(shí)現(xiàn)多線程。

2.2 Java中的線程

特別注意:這些線程的狀態(tài)時(shí)JVM中的線程狀態(tài)!不是操作系統(tǒng)中的線程狀態(tài)。

2.2.1 操作系統(tǒng)中的進(jìn)程(線程)狀態(tài)**(區(qū)分和JVM中的線程狀態(tài))**

這里需要著重解釋一點(diǎn),在現(xiàn)在的操作系統(tǒng)中,因?yàn)榫€程依舊被視為輕量級(jí)進(jìn)程,所以操作系統(tǒng)中線程的狀態(tài)實(shí)際上和進(jìn)程狀態(tài)是一致的模型。

2.2.2 操作系統(tǒng)中線程和Java線程狀態(tài)的關(guān)系:

從實(shí)際意義上來(lái)講,操作系統(tǒng)中的線程除去newterminated狀態(tài),一個(gè)線程真實(shí)存在的狀態(tài),只有:

  • ready:表示線程已經(jīng)被創(chuàng)建,正在等待系統(tǒng)調(diào)度分配CPU使用權(quán)。
  • running:表示線程獲得了CPU使用權(quán),正在進(jìn)行運(yùn)算
  • waiting:表示線程等待(或者說(shuō)掛起),讓出CPU資源給其他線程使用

為什么除去newterminated狀態(tài)?

是因?yàn)檫@兩種狀態(tài)實(shí)際上并不存在于線程運(yùn)行中,所以也沒(méi)什么實(shí)際討論的意義。

對(duì)于Java中的線程狀態(tài):

無(wú)論是Timed Waiting ,Waiting還是Blocked,對(duì)應(yīng)的都是操作系統(tǒng)線程的**waiting(等待**)狀態(tài)。

Runnable狀態(tài),則對(duì)應(yīng)了操作系統(tǒng)中的readyrunning狀態(tài)。

而對(duì)不同的操作系統(tǒng),由于本身設(shè)計(jì)思路不一樣,對(duì)于線程的設(shè)計(jì)也存在種種差異,所以JVM在設(shè)計(jì)上,就已經(jīng)聲明:

虛擬機(jī)中的線程狀態(tài),不反應(yīng)任何操作系統(tǒng)線程狀態(tài)

所以我上面說(shuō)的那么多,只是作為理解模型,Java線程和操作系統(tǒng)線程,實(shí)際上同根同源,但又相差甚遠(yuǎn)。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論