成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java 線程實(shí)現(xiàn)方式

曹金海 / 3411人閱讀

摘要:線程的可能實(shí)現(xiàn)方式基本上主流的操作系統(tǒng)都支持線程,也提供了線程的實(shí)現(xiàn)。使用用戶線程和內(nèi)核線程混合實(shí)現(xiàn)在這種混合實(shí)現(xiàn)下,既存在用戶線程,也存在內(nèi)核線程。

進(jìn)程與線程

在傳統(tǒng)的操作系統(tǒng)中,最核心的概念是“進(jìn)程”,進(jìn)程是對(duì)正在運(yùn)行的程序的一個(gè)抽象。
進(jìn)程的存在讓“并行”成為了可能,在一個(gè)操作系統(tǒng)中,允許運(yùn)行著多個(gè)進(jìn)程,這些進(jìn)程“看起來”是同時(shí)在運(yùn)行的。
如果我們的計(jì)算機(jī)同時(shí)運(yùn)行著 web 瀏覽器、電子郵件客戶端、即時(shí)通訊軟件例如QQ微信等多個(gè)進(jìn)程,我們感覺這些進(jìn)程都是同時(shí)在運(yùn)行的,假設(shè)這臺(tái)計(jì)算機(jī)搭配的是多個(gè) CPU 或者 多核 CPU,那么這種多個(gè)進(jìn)程并行的現(xiàn)象可能一點(diǎn)也不奇怪,完全可以為每個(gè)進(jìn)程多帶帶分配一個(gè) CPU,這樣就實(shí)現(xiàn)了多進(jìn)程并行。
然而事實(shí)上,在計(jì)算機(jī)只有一個(gè) CPU 的情況下,它也能給人類一種感覺:多個(gè)進(jìn)程同時(shí)在運(yùn)行。但人類的感覺往往是比較模糊的,不精確的。事實(shí)是由于 CPU 的計(jì)算速度非常地快,它能快速地在各個(gè)進(jìn)程之間切換,在某一瞬間,CPU 只能運(yùn)行一個(gè)進(jìn)程,但一秒鐘之內(nèi),它就能通過快速切換,讓人產(chǎn)生多個(gè)進(jìn)程同時(shí)在運(yùn)行的錯(cuò)覺。
在操作系統(tǒng)中,為什么在進(jìn)程的基礎(chǔ)上,又衍生出了線程的概念呢?

由于對(duì)于一些進(jìn)程而言,它內(nèi)部會(huì)發(fā)生多種活動(dòng),有些活動(dòng)可能會(huì)在某個(gè)時(shí)間里阻塞,有些活動(dòng)不會(huì),如果通過線程將這些活動(dòng)分離開使它們能夠并行地運(yùn)行,則設(shè)計(jì)程序的時(shí)候會(huì)更加簡(jiǎn)單。

線程比進(jìn)程的創(chuàng)建更加輕量級(jí),性能消耗更少

如果一個(gè)進(jìn)程既需要 CPU 計(jì)算,也需要I/O處理,擁有多線程允許這些活動(dòng)重疊進(jìn)行,加快整個(gè)進(jìn)程的執(zhí)行速度。

每一個(gè)進(jìn)程在操作系統(tǒng)中都擁有獨(dú)立的一塊內(nèi)存地址空間,該進(jìn)程創(chuàng)建的所有線程共享這塊內(nèi)存,支持多線程的操作系統(tǒng),會(huì)讓線程作為 CPU 調(diào)度的最小單位。CPU 的時(shí)間片在不同的線程之間進(jìn)行分配。

線程的可能實(shí)現(xiàn)方式

基本上主流的操作系統(tǒng)都支持線程,也提供了線程的實(shí)現(xiàn)。而 Java 語言為了應(yīng)對(duì)不同硬件和操作系統(tǒng)的差異,提供了對(duì)線程操作的統(tǒng)一抽象,在 Java 中我們使用 Thread 類來代表一個(gè)線程。
Thread 的具體實(shí)現(xiàn)可能會(huì)有不同的實(shí)現(xiàn)方式:

使用內(nèi)核線程實(shí)現(xiàn)

內(nèi)核線程是操作系統(tǒng)內(nèi)核支持的線程,在內(nèi)核中有一個(gè)線程表用來記錄系統(tǒng)中的所有線程,創(chuàng)建或者銷毀一個(gè)線程時(shí),都需要涉及到系統(tǒng)調(diào)用,然后再內(nèi)核中對(duì)線程表進(jìn)行更新操作。對(duì)內(nèi)核線程的阻塞以及其它操作,都涉及到系統(tǒng)調(diào)用,系統(tǒng)調(diào)用的代價(jià)都比較大,涉及到在用戶態(tài)和內(nèi)核態(tài)之間的來回切換。此外,內(nèi)核內(nèi)部有線程調(diào)度器,用于決定應(yīng)該將 CPU 時(shí)間片分配個(gè)哪個(gè)線程。
程序一般不會(huì)直接操作內(nèi)核線程,而是使用內(nèi)核線程的一種高級(jí)接口,輕量級(jí)進(jìn)程。輕量級(jí)進(jìn)程與內(nèi)核線程之間的關(guān)系是 1:1,每一個(gè)輕量級(jí)進(jìn)程內(nèi)部都有一個(gè)內(nèi)核線程支持。

上圖中, LWP 指 Light Weight Process,即輕量級(jí)進(jìn)程;KLT 指 Kernel Level Thread,即內(nèi)核線程。

使用用戶線程實(shí)現(xiàn)

用戶線程是程序或者編程語言自己實(shí)現(xiàn)的線程庫,系統(tǒng)內(nèi)核無法感知到這些線程的存在。用戶線程的建立、同步、銷毀和調(diào)度,都在用戶態(tài)中完成,無須內(nèi)核的幫助,不需要進(jìn)行系統(tǒng)調(diào)用,這樣的好處是對(duì)于線程的操作是非常高效的。在這種情況下,進(jìn)程和用戶線程的比例是 1 :N。

用戶態(tài)線程面對(duì)如何阻塞線程時(shí),會(huì)面臨困難,阻塞一個(gè)用戶態(tài)線程會(huì)出現(xiàn)把整個(gè)進(jìn)程都阻塞的情況,多線程也就失去了意義。因?yàn)槿鄙賰?nèi)核的支持,所以很多需要利用內(nèi)核才能完成的工作,例如阻塞與喚醒線程、多 CPU 環(huán)境下線程的映射等,都需要用戶程序去實(shí)現(xiàn),實(shí)現(xiàn)起來會(huì)異常困難。

使用用戶線程和內(nèi)核線程混合實(shí)現(xiàn)

在這種混合實(shí)現(xiàn)下,既存在用戶線程,也存在內(nèi)核線程。用戶態(tài)線程的創(chuàng)建、切換這些操作依然很高效,并且用戶態(tài)實(shí)現(xiàn)的線程,比較容易加大線程的規(guī)模。需要操作系統(tǒng)內(nèi)核支持的功能,則通過內(nèi)核線程來做到,例如映射到不同的處理器上、處理線程的阻塞與喚醒以及內(nèi)核線程的調(diào)度等。這種實(shí)現(xiàn)依然會(huì)使用到輕量級(jí)進(jìn)程 LWP,它是用戶線程和內(nèi)核線程之間的橋梁。

Java 線程的實(shí)現(xiàn)

在 JDK1.2 之前, Java 的線程是使用用戶線程實(shí)現(xiàn)的,在 JDK1.2 之后,Java 才采用操作系統(tǒng)原生支持的線程模型來實(shí)現(xiàn),Java 線程模型的實(shí)現(xiàn)方式,主要取決于操作系統(tǒng)。對(duì)于 Oracle JDK 來說,在 Windows 和 Linux 上的線程模型是采用一對(duì)一的方式實(shí)現(xiàn)的,即一條 Java 線程映射到一條輕量級(jí)進(jìn)程(內(nèi)核線程)。而在 Solaris 平臺(tái)中,Java 則支持 1 :1 和 N : M 的線程模型。

線程的阻塞與等待

Java 中的線程的狀態(tài)有以下幾種:New,Runnable,Waiting, TimedWaiting, Blocked,Terminated。

NEW:線程初創(chuàng)建,未運(yùn)行

RUNNABLE:線程正在運(yùn)行,但不一定消耗 CPU

BLOCKED:線程正在等待另外一個(gè)線程釋放鎖

WAITING:線程執(zhí)行了 wait, join, LockSupport.park() 方法

TIMED_WAITING:線程調(diào)用了sleep, wait, join, LockSupport.parkNanos() 等方法,與 WAITING 狀態(tài)不同的是,這些方法帶有表示時(shí)間的參數(shù)。

其中 Blocked 和 Waiting 有個(gè)重要的區(qū)別是,阻塞(Blocked)狀態(tài)的線程在等待獲取一個(gè)排他鎖,例如線程在等待進(jìn)入一個(gè)synchronized關(guān)鍵字包圍的臨界區(qū)時(shí),就進(jìn)入 Blocked 狀態(tài)。而 Waiting 狀態(tài)則是在等待被喚醒,或者等待一段時(shí)間。

參考資料

《深入理解 Java 虛擬機(jī)》第二版 - 周志明
《現(xiàn)代操作系統(tǒng)》第四版 - Andrew S. Tanenbaum

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77139.html

相關(guān)文章

  • 想進(jìn)大廠?50個(gè)多線程面試題,你會(huì)多少?【后25題】(二)

    摘要:大多數(shù)待遇豐厚的開發(fā)職位都要求開發(fā)者精通多線程技術(shù)并且有豐富的程序開發(fā)調(diào)試優(yōu)化經(jīng)驗(yàn),所以線程相關(guān)的問題在面試中經(jīng)常會(huì)被提到。掌握了這些技巧,你就可以輕松應(yīng)對(duì)多線程和并發(fā)面試了。進(jìn)入等待通行準(zhǔn)許時(shí),所提供的對(duì)象。 最近看到網(wǎng)上流傳著,各種面試經(jīng)驗(yàn)及面試題,往往都是一大堆技術(shù)題目貼上去,而沒有答案。 不管你是新程序員還是老手,你一定在面試中遇到過有關(guān)線程的問題。Java語言一個(gè)重要的特點(diǎn)就...

    caozhijian 評(píng)論0 收藏0
  • java面試題

    摘要:抽象類表示的是,這個(gè)對(duì)象是什么。下面提供了一個(gè)完整的有返回結(jié)果的多線程測(cè)試?yán)?,在下?yàn)證過沒問題可以直接使用。創(chuàng)建固定數(shù)目線程的線程池。創(chuàng)建一個(gè)支持定時(shí)及周期性的任務(wù)執(zhí)行的線程池,多數(shù)情況下可用來替代類。 接口和抽象類有什么區(qū)別你選擇使用接口和抽象類的依據(jù)是什么? 接口和抽象類的概念不一樣。接口是對(duì)動(dòng)作的抽象,抽象類是對(duì)根源的抽象。抽象類表示的是,這個(gè)對(duì)象是什么。接口表示的是,這個(gè)對(duì)象...

    lentrue 評(píng)論0 收藏0
  • Java并發(fā)編程筆記(一)

    摘要:并發(fā)編程實(shí)戰(zhàn)水平很高,然而并不是本好書。一是多線程的控制,二是并發(fā)同步的管理。最后,使用和來關(guān)閉線程池,停止其中的線程。當(dāng)線程調(diào)用或等阻塞時(shí),對(duì)這個(gè)線程調(diào)用會(huì)使線程醒來,并受到,且線程的中斷標(biāo)記被設(shè)置。 《Java并發(fā)編程實(shí)戰(zhàn)》水平很高,然而并不是本好書。組織混亂、長篇大論、難以消化,中文翻譯也較死板。這里是一篇批評(píng)此書的帖子,很是貼切。俗話說:看到有這么多人罵你,我就放心了。 然而知...

    cnsworder 評(píng)論0 收藏0
  • 如何創(chuàng)建并運(yùn)行java線程

    摘要:例子如下可以用如下方式創(chuàng)建并運(yùn)行上述子類一旦線程啟動(dòng)后方法就會(huì)立即返回,而不會(huì)等待到方法執(zhí)行完畢才返回。但是,事實(shí)上方法并非是由剛創(chuàng)建的新線程所執(zhí)行的,而是被創(chuàng)建新線程的當(dāng)前線程所執(zhí)行了。這是因?yàn)榫€程是并行執(zhí)行而非順序的。 showImg(http://segmentfault.com/img/bVbN5u); Java線程類也是一個(gè)object類,它的實(shí)例都繼承自java.lang...

    宋華 評(píng)論0 收藏0
  • java

    摘要:多線程編程這篇文章分析了多線程的優(yōu)缺點(diǎn),如何創(chuàng)建多線程,分享了線程安全和線程通信線程池等等一些知識(shí)。 中間件技術(shù)入門教程 中間件技術(shù)入門教程,本博客介紹了 ESB、MQ、JMS 的一些知識(shí)... SpringBoot 多數(shù)據(jù)源 SpringBoot 使用主從數(shù)據(jù)源 簡(jiǎn)易的后臺(tái)管理權(quán)限設(shè)計(jì) 從零開始搭建自己權(quán)限管理框架 Docker 多步構(gòu)建更小的 Java 鏡像 Docker Jav...

    honhon 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<