java线程实现方式
線程的實現(xiàn)
各個線程既可以共享進(jìn)程資源(內(nèi)存地址、文件I/O等),又可以獨立調(diào)度(線程是CPU調(diào)度的基本單位)。 每個已經(jīng)執(zhí)行start()且還未結(jié)束的java.lang.Thread類的實例就代表了一個線程。Thread的所有關(guān)鍵方法都是聲明為Native的。在Java API中,一個Native方法往往意味著這個方法沒有使用或無法使用平臺無關(guān)的手段來實現(xiàn)(當(dāng)然也可能是為了執(zhí)行效率而使用Native方法,不過,通常最高效的手段也就是平臺相關(guān)的手段)。 實現(xiàn)線程主要有3種方式: 1)使用內(nèi)核線程實現(xiàn) 2)使用用戶線程實現(xiàn) 3)使用用戶線程加輕量級進(jìn)程混合實現(xiàn)
使用內(nèi)核線程(Kernel-Level Thread,KLT)實現(xiàn)
內(nèi)核線程就是直接由操作系統(tǒng)內(nèi)核(Kernel)支持的線程,這種線程由內(nèi)核來完成線程切換,內(nèi)核通過操縱調(diào)度器(Scheduler)對線程進(jìn)行調(diào)度,并負(fù)責(zé)將線程的任務(wù)映射到各個處理器上。每個內(nèi)核線程可以視為內(nèi)核的一個分身,這樣操作系統(tǒng)就有能力同時處理多件事情,支持多線程的內(nèi)核就叫做多線程內(nèi)核(Multi-Threads Kernel)。
程序一般不會直接去使用內(nèi)核線程,而是去使用內(nèi)核線程的一種高級接口--輕量級進(jìn)程(Light Weight Process,LWP),輕量級進(jìn)程就是我們通常意義上所講的線程,由于每個輕量級進(jìn)程都由一個內(nèi)核線程支持,因此只有先支持內(nèi)核線程,才能有輕量級進(jìn)程。這種輕量級進(jìn)程與內(nèi)核線程之間1:1的關(guān)系稱為一對一的線程模型。 輕量級進(jìn)程與內(nèi)核線程之間1:1的關(guān)系:
由于內(nèi)核線程的支持,每個輕量級進(jìn)程都成為一個獨立的調(diào)度單元,即使有一個輕量級進(jìn)程在系統(tǒng)調(diào)用中阻塞了,也不會影響整個進(jìn)程繼續(xù)工作,但是輕量級進(jìn)程具有它的局限性:首先,由于是基于內(nèi)核線程實現(xiàn)的,所以各種線程操作,如創(chuàng)建、析構(gòu)及同步,都需要進(jìn)行系統(tǒng)調(diào)用。而系統(tǒng)調(diào)用的代價相對較高,需要在用戶態(tài)(User Mode)和內(nèi)核態(tài)(Kernel Mode)中來回切換。其次,每個輕量級進(jìn)程都需要有一個內(nèi)核線程的支持,因此輕量級進(jìn)程要消耗一定的內(nèi)核資源(如內(nèi)核線程的棧空間),因此一個系統(tǒng)支持輕量級進(jìn)程的數(shù)量是有限的。
使用用戶線程實現(xiàn)
從廣義上來講,一個線程只要不是內(nèi)核線程,就可以認(rèn)為是用戶線程(User Thread,UT),輕量級進(jìn)程也屬于用戶線程,但輕量級進(jìn)程的實現(xiàn)始終是建立在內(nèi)核之上的,許多操作都要進(jìn)行系統(tǒng)調(diào)用,效率會受到限制。
而狹義上的用戶線程指的是完全建立在用戶空間的線程庫上,系統(tǒng)內(nèi)核不能感知線程存在的實現(xiàn)。用戶線程的建立、同步、銷毀和調(diào)度完全在用戶態(tài)中完成,不需要內(nèi)核的幫助。如果程序?qū)崿F(xiàn)得當(dāng),這種線程不需要切換到內(nèi)核態(tài),因此操作可以是非??焖偾业拖牡?#xff0c;也可以支持規(guī)模更大的線程數(shù)量,部分高性能數(shù)據(jù)庫中的多線程就是由用戶線程實現(xiàn)的。這種進(jìn)程與用戶線程之間1:N的關(guān)系稱為一對多的線程模型:
使用用戶線程的優(yōu)勢在于不需要系統(tǒng)內(nèi)核支援,劣勢也在于沒有系統(tǒng)內(nèi)核的支援,所有的線程操作都需要用戶程序自己處理。線程的創(chuàng)建、切換和調(diào)度都是需要考慮的問題,而且由于操作系統(tǒng)只把處理器資源分配到進(jìn)程,那諸如“阻塞如何處理”,“多處理器系統(tǒng)中如何將線程映射到其它處理器上”這類問題解決起來將會異常困難,甚至不可能完成。除了以前在不支持多線程的操作系統(tǒng)中(如DOS)的多線程程序與少數(shù)有特殊需求的程序外,現(xiàn)在使用用戶線程的程序越來越少了,Java、Ruby等語言都曾經(jīng)使用過用戶線程,最終又都放棄使用它。
使用用戶線程加輕量級進(jìn)程混合實現(xiàn)
在這種混合實現(xiàn)下,即存在用戶線程,也存在輕量級進(jìn)程。用戶線程還是完全建立在用戶空間中,因此用戶線程的創(chuàng)建、切換、析構(gòu)等操作依然廉價,并且可以支持大規(guī)模的用戶線程并發(fā)。而操作系統(tǒng)提供支持的輕量級進(jìn)程則作為用戶線程和內(nèi)核線程之間的橋梁,這樣可以使用內(nèi)核提供的線程調(diào)度功能及處理器映射,并且用戶線程的系統(tǒng)調(diào)用要通過輕量級進(jìn)程來完成,大大降低了整個進(jìn)程被完全阻塞的風(fēng)險。在這種混合模式中,用戶線程與輕量級進(jìn)程的數(shù)量比是不定的,即為N:M的關(guān)系:
許多UNIX系列的操作系統(tǒng),如Salaris、HP-UX等都提供了N:M的線程模型實現(xiàn)。
Java線程的實現(xiàn)
Java線程在JDK1.2之前,是基于稱為“綠色線程”(Green Threads)的用戶線程實現(xiàn)的,而在JDK1.2中,線程模型替換為基于操作系統(tǒng)原生線程模型來實現(xiàn)。因此,在目前的JDK版本中,操作系統(tǒng)支持怎樣的線程模型,在很大程度上決定了Java虛擬機(jī)的線程是怎樣映射的,這點在不同的平臺上沒有辦法達(dá)成一致,虛擬機(jī)規(guī)范中也并未限定Java線程需要使用哪種線程模型來實現(xiàn)。線程模型只對線程的并發(fā)規(guī)模和操作成本產(chǎn)生影響,對Java程序的編碼和運行過程來說,這些差異都是透明的。
對于Sun JDK來說,它的Windows版與Linux版都是使用一對一的線程模型實現(xiàn)的,一條Java線程就映射到一條輕量級進(jìn)程之中,因為Windows和Linux系統(tǒng)提供的線程模型就是一對一的。而在Solari平臺中,由于操作系統(tǒng)的線程特性可以同時支持一對一(通過Bound Threads或Alternate Libthread實現(xiàn))及一對多(通過LWP/Thread Based Synchronization實現(xiàn))的線程模型,因此在Solaris版的JDK中也對應(yīng)提供了兩個平臺專有的虛擬機(jī)參數(shù):-XX:+UseLWPSynchronization(默認(rèn)值)和-XX:+UseBoundThreads來明確指定虛擬機(jī)使用哪種線程模型。
總結(jié)
以上是生活随笔為你收集整理的java线程实现方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在线教育这条取经路,有道词典何时能修成正
- 下一篇: 通信类