線(xiàn)程

線(xiàn)程(英語(yǔ):thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位。它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位。一條線(xiàn)程指的是進(jìn)程中一個(gè)單一順序的控制流,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線(xiàn)程,每條線(xiàn)程并行執(zhí)行不同的任務(wù)。在Unix System V及SunOS中也被稱(chēng)為輕量進(jìn)程(lightweight processes),但輕量進(jìn)程更多指內(nèi)核線(xiàn)程(kernel thread),而把用戶(hù)線(xiàn)程(user thread)稱(chēng)為線(xiàn)程。
線(xiàn)程是獨(dú)立調(diào)度和分派的基本單位。線(xiàn)程可以為操作系統(tǒng)內(nèi)核調(diào)度的內(nèi)核線(xiàn)程,如Win32線(xiàn)程;由用戶(hù)進(jìn)程自行調(diào)度的用戶(hù)線(xiàn)程,如Linux平臺(tái)的POSIX Thread;或者由內(nèi)核與用戶(hù)進(jìn)程,如Windows 7的線(xiàn)程,進(jìn)行混合調(diào)度。
同一進(jìn)程中的多條線(xiàn)程將共享該進(jìn)程中的全部系統(tǒng)資源,如虛擬地址空間,文件描述符和信號(hào)處理等等。但同一進(jìn)程中的多個(gè)線(xiàn)程有各自的調(diào)用棧(call stack),自己的寄存器環(huán)境(register context),自己的線(xiàn)程本地存儲(chǔ)(thread-local storage)。
一個(gè)進(jìn)程可以有很多線(xiàn)程,每條線(xiàn)程并行執(zhí)行不同的任務(wù)。
在多核或多CPU,或支持Hyper-threading的CPU上使用多線(xiàn)程程序設(shè)計(jì)的好處是顯而易見(jiàn),即提高了程序的執(zhí)行吞吐率。在單CPU單核的計(jì)算機(jī)上,使用多線(xiàn)程技術(shù),也可以把進(jìn)程中負(fù)責(zé)I/O處理、人機(jī)交互而常被阻塞的部分與密集計(jì)算的部分分開(kāi)來(lái)執(zhí)行,編寫(xiě)專(zhuān)門(mén)的workhorse線(xiàn)程執(zhí)行密集計(jì)算,從而提高了程序的執(zhí)行效率。

線(xiàn)程基本信息

中文名 線(xiàn)程 外文名 thread
別????名 執(zhí)行緒;輕量進(jìn)程 提出者 dozer
應(yīng)用學(xué)科 計(jì)算機(jī) 多線(xiàn)程中 CPU的基本單位
定????義 程序執(zhí)行流的最小單元

進(jìn)程是資源分配的基本單位。所有與該進(jìn)程有關(guān)的資源,都被記錄在進(jìn)程控制塊PCB中。以表示該進(jìn)程擁有這些資源或正在使用它們。

另外,進(jìn)程也是搶占處理機(jī)的調(diào)度單位,它擁有一個(gè)完整的虛擬地址空間。當(dāng)進(jìn)程發(fā)生調(diào)度時(shí),不同的進(jìn)程擁有不同的虛擬地址空間,而同一進(jìn)程內(nèi)的不同線(xiàn)程共享同一地址空間。

與進(jìn)程相對(duì)應(yīng),線(xiàn)程與資源分配無(wú)關(guān),它屬于某一個(gè)進(jìn)程,并與進(jìn)程內(nèi)的其他線(xiàn)程一起共享進(jìn)程的資源。

線(xiàn)程只由相關(guān)堆棧(系統(tǒng)?;蛴脩?hù)棧)寄存器和線(xiàn)程控制表TCB組成。寄存器可被用來(lái)存儲(chǔ)線(xiàn)程內(nèi)的局部變量,但不能存儲(chǔ)其他線(xiàn)程的相關(guān)變量。

通常在一個(gè)進(jìn)程中可以包含若干個(gè)線(xiàn)程,它們可以利用進(jìn)程所擁有的資源。在引入線(xiàn)程的操作系統(tǒng)中,通常都是把進(jìn)程作為分配資源的基本單位,而把線(xiàn)程作為獨(dú)立運(yùn)行和獨(dú)立調(diào)度的基本單位。由于線(xiàn)程比進(jìn)程更小,基本上不擁有系統(tǒng)資源,故對(duì)它的調(diào)度所付出的開(kāi)銷(xiāo)就會(huì)小得多,能更高效的提高系統(tǒng)內(nèi)多個(gè)程序間并發(fā)執(zhí)行的程度,從而顯著提高系統(tǒng)資源的利用率和吞吐量。因而近年來(lái)推出的通用操作系統(tǒng)都引入了線(xiàn)程,以便進(jìn)一步提高系統(tǒng)的并發(fā)性,并把它視為現(xiàn)代操作系統(tǒng)的一個(gè)重要指標(biāo)。

線(xiàn)程與進(jìn)程的區(qū)別可以歸納為以下4點(diǎn):

1)地址空間和其它資源(如打開(kāi)文件):進(jìn)程間相互獨(dú)立,同一進(jìn)程的各線(xiàn)程間共享。某進(jìn)程內(nèi)的線(xiàn)程在其它進(jìn)程不可見(jiàn)。

2)通信:進(jìn)程間通信IPC,線(xiàn)程間可以直接讀寫(xiě)進(jìn)程數(shù)據(jù)段(如全局變量)來(lái)進(jìn)行通信——需要進(jìn)程同步和互斥手段的輔助,以保證數(shù)據(jù)的一致性。

3)調(diào)度和切換:線(xiàn)程上下文切換比進(jìn)程上下文切換要快得多。

4)在多線(xiàn)程O(píng)S中,進(jìn)程不是一個(gè)可執(zhí)行的實(shí)體。

線(xiàn)程造價(jià)信息

市場(chǎng)價(jià) 信息價(jià) 詢(xún)價(jià)
材料名稱(chēng) 規(guī)格/型號(hào) 市場(chǎng)價(jià)
(除稅)
工程建議價(jià)
(除稅)
行情 品牌 單位 稅率 供應(yīng)商 報(bào)價(jià)日期
萬(wàn)里浮雕 品種:浮雕;規(guī)格(mm):1100×790;型號(hào):FD-029A; 查看價(jià)格 查看價(jià)格

三奇帝

13% 石家莊東方紫銅浮雕工藝品有限公司
萬(wàn)里金雕 品種:金雕;規(guī)格(mm):1984×944;銅板尺寸(cm):1500×500;外框尺寸(cm):1984×944;說(shuō)明:歐式框;型號(hào):JD 查看價(jià)格 查看價(jià)格

三奇帝

13% 石家莊東方紫銅浮雕工藝品有限公司
萬(wàn)里金雕 品種:金雕;規(guī)格(mm):1720×720;銅板尺寸(cm):1500×500;外框尺寸(cm):1720×720;說(shuō)明:普通框;型號(hào):JD 查看價(jià)格 查看價(jià)格

三奇帝

13% 石家莊東方紫銅浮雕工藝品有限公司
萬(wàn)里浮雕 品種:浮雕;規(guī)格(mm):2840×1230;型號(hào):FD-029B; 查看價(jià)格 查看價(jià)格

三奇帝

13% 石家莊東方紫銅浮雕工藝品有限公司
LED品線(xiàn)式辦公照明 產(chǎn)品型號(hào):PLP1203;色溫:4000K;裝箱數(shù):4;尺寸1:1200×60×65;顏色:銀灰色; 查看價(jià)格 查看價(jià)格

品上照明

13% 重慶同界源科技有限公司
駿瓷片JAR07400系列腰線(xiàn) JX27*70A*07400*010 300*450 白色 查看價(jià)格 查看價(jià)格

13% 廣東唯美陶瓷有限公司馬可波羅大武漢家裝廣場(chǎng)
辦公燈 產(chǎn)品型號(hào):PLP1203;裝箱數(shù):2;規(guī)格:Ra≥70;色溫:6000k;尺寸1:150×1200mm;配件:鋁合金燈體;功率(W):36; 查看價(jià)格 查看價(jià)格

品上照明

13% 重慶同界源科技有限公司
辦公燈 產(chǎn)品型號(hào):PLP1203;規(guī)格:Ra≥70;色溫:6000k;尺寸1:200×1200mm;配件:鋁合金燈體;功率(W):48; 查看價(jià)格 查看價(jià)格

品上照明

13% 重慶同界源科技有限公司
材料名稱(chēng) 規(guī)格/型號(hào) 除稅
信息價(jià)
含稅
信息價(jià)
行情 品牌 單位 稅率 地區(qū)/時(shí)間
導(dǎo)線(xiàn)卷車(chē) DSJ23-122 查看價(jià)格 查看價(jià)格

臺(tái)班 汕頭市2012年4季度信息價(jià)
導(dǎo)線(xiàn)卷車(chē) DSJ23-122 查看價(jià)格 查看價(jià)格

臺(tái)班 汕頭市2012年3季度信息價(jià)
導(dǎo)線(xiàn)卷車(chē) DSJ23-122 查看價(jià)格 查看價(jià)格

臺(tái)班 廣州市2011年1季度信息價(jià)
導(dǎo)線(xiàn)卷車(chē) DSJ23-122 查看價(jià)格 查看價(jià)格

臺(tái)班 汕頭市2010年1季度信息價(jià)
導(dǎo)線(xiàn)卷車(chē) DSJ23-122 查看價(jià)格 查看價(jià)格

臺(tái)班 汕頭市2009年2季度信息價(jià)
導(dǎo)線(xiàn)卷車(chē) DSJ23-122 查看價(jià)格 查看價(jià)格

臺(tái)班 汕頭市2009年1季度信息價(jià)
導(dǎo)線(xiàn)卷車(chē) DSJ23-122 查看價(jià)格 查看價(jià)格

臺(tái)班 汕頭市2008年3季度信息價(jià)
導(dǎo)線(xiàn)卷車(chē) DSJ23-122 查看價(jià)格 查看價(jià)格

臺(tái)班 汕頭市2008年2季度信息價(jià)
材料名稱(chēng) 規(guī)格/需求量 報(bào)價(jià)數(shù) 最新報(bào)價(jià)
(元)
供應(yīng)商 報(bào)價(jià)地區(qū) 最新報(bào)價(jià)時(shí)間
線(xiàn)抄表主機(jī) 詳見(jiàn)圖紙|1套 3 查看價(jià)格 杭州源牌科技股份有限公司建筑環(huán)境設(shè)備分公司 廣東   2018-05-14
1年課服務(wù) 課程教學(xué)|1套 2 查看價(jià)格 溫州貝爾教儀有限公司 廣東   2022-05-24
三回濕背 B-B1-1|1臺(tái) 3 查看價(jià)格 湖北天鹿鍋爐有限公司 廣東  深圳市 2019-06-03
三回濕背 B-B1-2|1臺(tái) 3 查看價(jià)格 湖北天鹿鍋爐有限公司 廣東  深圳市 2019-06-03
3年課服務(wù) 詳見(jiàn)線(xiàn)下技術(shù)要求文件|1套 2 查看價(jià)格 溫州貝爾教儀有限公司 廣東   2022-05-24
IP網(wǎng)絡(luò)遠(yuǎn)傳尋呼站 T-6702|1臺(tái) 1 查看價(jià)格 廣州市保倫電子有限公司 全國(guó)   2019-04-29
三回濕背 蒸發(fā)量2000kg/h|1套 2 查看價(jià)格 德國(guó)BOSCH博世鍋爐 全國(guó)   2019-06-27
臥式三回濕背式鍋爐 400匹馬力,蒸汽出率6260kg/h,大約噸位6.3t/h,油氣兩用型|7臺(tái) 4 查看價(jià)格 四川省樂(lè)山市福山鍋爐有限公司貴陽(yáng)銷(xiāo)售處 貴州  貴陽(yáng)市 2016-01-02

線(xiàn)程的引入:

60年代,在OS中能擁有資源和獨(dú)立運(yùn)行的基本單位是進(jìn)程,然而隨著計(jì)算機(jī)技術(shù)的發(fā)展,進(jìn)程出現(xiàn)了很多弊端,一是由于進(jìn)程是資源擁有者,創(chuàng)建、撤消與切換存在較大的時(shí)空開(kāi)銷(xiāo),因此需要引入輕型進(jìn)程;二是由于對(duì)稱(chēng)多處理機(jī)(SMP)出現(xiàn),可以滿(mǎn)足多個(gè)運(yùn)行單位,而多個(gè)進(jìn)程并行開(kāi)銷(xiāo)過(guò)大。

因此在80年代,出現(xiàn)了能獨(dú)立運(yùn)行的基本單位——線(xiàn)程(Threads)。

在多線(xiàn)程O(píng)S中,通常是在一個(gè)進(jìn)程中包括多個(gè)線(xiàn)程,每個(gè)線(xiàn)程都是作為利用CPU的基本單位,是花費(fèi)最小開(kāi)銷(xiāo)的實(shí)體。線(xiàn)程具有以下屬性。

1)輕型實(shí)體

線(xiàn)程中的實(shí)體基本上不擁有系統(tǒng)資源,只是有一點(diǎn)必不可少的、能保證獨(dú)立運(yùn)行的資源。

線(xiàn)程的實(shí)體包括程序、數(shù)據(jù)和TCB。線(xiàn)程是動(dòng)態(tài)概念,它的動(dòng)態(tài)特性由線(xiàn)程控制塊TCB(Thread Control Block)描述。TCB包括以下信息:

(1)線(xiàn)程狀態(tài)。

(2)當(dāng)線(xiàn)程不運(yùn)行時(shí),被保存的現(xiàn)場(chǎng)資源。

(3)一組執(zhí)行堆棧。

(4)存放每個(gè)線(xiàn)程的局部變量主存區(qū)。

(5)訪問(wèn)同一個(gè)進(jìn)程中的主存和其它資源。

用于指示被執(zhí)行指令序列的程序計(jì)數(shù)器、保留局部變量、少數(shù)狀態(tài)參數(shù)和返回地址等的一組寄存器和堆棧。

2)獨(dú)立調(diào)度和分派的基本單位。

在多線(xiàn)程O(píng)S中,線(xiàn)程是能獨(dú)立運(yùn)行的基本單位,因而也是獨(dú)立調(diào)度和分派的基本單位。由于線(xiàn)程很“輕”,故線(xiàn)程的切換非常迅速且開(kāi)銷(xiāo)?。ㄔ谕贿M(jìn)程中的)。

3)可并發(fā)執(zhí)行。

在一個(gè)進(jìn)程中的多個(gè)線(xiàn)程之間,可以并發(fā)執(zhí)行,甚至允許在一個(gè)進(jìn)程中所有線(xiàn)程都能并發(fā)執(zhí)行;同樣,不同進(jìn)程中的線(xiàn)程也能并發(fā)執(zhí)行,充分利用和發(fā)揮了處理機(jī)與外圍設(shè)備并行工作的能力。

4)共享進(jìn)程資源。

在同一進(jìn)程中的各個(gè)線(xiàn)程,都可以共享該進(jìn)程所擁有的資源,這首先表現(xiàn)在:所有線(xiàn)程都具有相同的地址空間(進(jìn)程的地址空間),這意味著,線(xiàn)程可以訪問(wèn)該地址空間的每一個(gè)虛地址;此外,還可以訪問(wèn)進(jìn)程所擁有的已打開(kāi)文件、定時(shí)器、信號(hào)量機(jī)構(gòu)等。由于同一個(gè)進(jìn)程內(nèi)的線(xiàn)程共享內(nèi)存和文件,所以線(xiàn)程之間互相通信不必調(diào)用內(nèi)核。

線(xiàn)程常見(jiàn)問(wèn)題

(1)創(chuàng)建線(xiàn)程

當(dāng)創(chuàng)建一個(gè)新的進(jìn)程時(shí),也創(chuàng)建一個(gè)新的線(xiàn)程,進(jìn)程中的線(xiàn)程可以在同一進(jìn)程中創(chuàng)建新的線(xiàn)程。

(2)終止線(xiàn)程

可以正常終止自己,也可能某個(gè)線(xiàn)程執(zhí)行錯(cuò)誤,由其它線(xiàn)程強(qiáng)行終止。終止線(xiàn)程操作主要負(fù)責(zé)釋放線(xiàn)程占有的寄存器和棧

(3)阻塞線(xiàn)程

當(dāng)線(xiàn)程等待每個(gè)事件無(wú)法運(yùn)行時(shí),停止其運(yùn)行。

(4)喚醒線(xiàn)程

當(dāng)阻塞線(xiàn)程的事件發(fā)生時(shí),將被阻塞的線(xiàn)程狀態(tài)置為就緒態(tài),將其掛到就緒隊(duì)列。進(jìn)程仍然具有與執(zhí)行相關(guān)的狀態(tài)。例如,所謂進(jìn)程處于“執(zhí)行”狀態(tài),實(shí)際上是指該進(jìn)程中的某線(xiàn)程正在執(zhí)行。對(duì)進(jìn)程施加的與進(jìn)程狀態(tài)有關(guān)的操作,也對(duì)其線(xiàn)程起作用。例如,把某個(gè)進(jìn)程掛起時(shí),該進(jìn)程中的所有線(xiàn)程也都被掛起,激活也是同樣。

線(xiàn)程的同步是Java多線(xiàn)程編程的難點(diǎn),往往開(kāi)發(fā)者搞不清楚什么是競(jìng)爭(zhēng)資源、什么時(shí)候需要考慮同步,怎么同步等等問(wèn)題,當(dāng)然,這些問(wèn)題沒(méi)有很明確的答案,但有些原則問(wèn)題需要考慮,是否有競(jìng)爭(zhēng)資源被同時(shí)改動(dòng)的問(wèn)題?對(duì)于同步,在具體的Java代碼中需要完成以下兩個(gè)操作:把競(jìng)爭(zhēng)訪問(wèn)的資源標(biāo)識(shí)為private;同步哪些修改變量的代碼,使用synchronized關(guān)鍵字同步方法或代碼。當(dāng)然這不是唯一控制并發(fā)安全的途徑。synchronized關(guān)鍵字使用說(shuō)明synchronized只能標(biāo)記非抽象的方法,不能標(biāo)識(shí)成員變量。為了演示同步方法的使用,構(gòu)建了一個(gè)信用卡賬戶(hù),起初信用額為100w,然后模擬透支、存款等多個(gè)操作。顯然銀行賬戶(hù)User對(duì)象是個(gè)競(jìng)爭(zhēng)資源,而多個(gè)并發(fā)操作的是賬戶(hù)方法oper(int x),當(dāng)然應(yīng)該在此方法上加上同步,并將賬戶(hù)的余額設(shè)為私有變量,禁止直接訪問(wèn)。

工作原理

線(xiàn)程是進(jìn)程中的實(shí)體,一個(gè)進(jìn)程可以擁有多個(gè)線(xiàn)程,一個(gè)線(xiàn)程必須有一個(gè)父進(jìn)程。線(xiàn)程不擁有系統(tǒng)資源,只有運(yùn)行必須的一些數(shù)據(jù)結(jié)構(gòu);它與父進(jìn)程的其它線(xiàn)程共享該進(jìn)程所擁有的全部資源。線(xiàn)程可以創(chuàng)建和撤消線(xiàn)程,從而實(shí)現(xiàn)程序的并發(fā)執(zhí)行。一般,線(xiàn)程具有就緒、阻塞和運(yùn)行三種基本狀態(tài)。

在多中央處理器的系統(tǒng)里,不同線(xiàn)程可以同時(shí)在不同的中央處理器上運(yùn)行,甚至當(dāng)它們屬于同一個(gè)進(jìn)程時(shí)也是如此。大多數(shù)支持多處理器的操作系統(tǒng)都提供編程接口來(lái)讓進(jìn)程可以控制自己的線(xiàn)程與各處理器之間的關(guān)聯(lián)度(affinity)。

有時(shí)候,線(xiàn)程也稱(chēng)作輕量級(jí)進(jìn)程。就象進(jìn)程一樣,線(xiàn)程在程序中是獨(dú)立的、并發(fā)的執(zhí)行路徑,每個(gè)線(xiàn)程有它自己的堆棧、自己的程序計(jì)數(shù)器和自己的局部變量。但是,與分隔的進(jìn)程相比,進(jìn)程中的線(xiàn)程之間的隔離程度要小。它們共享內(nèi)存、文件句柄和其它每個(gè)進(jìn)程應(yīng)有的狀態(tài)。

進(jìn)程可以支持多個(gè)線(xiàn)程,它們看似同時(shí)執(zhí)行,但互相之間并不同步。一個(gè)進(jìn)程中的多個(gè)線(xiàn)程共享相同的內(nèi)存地址空間,這就意味著它們可以訪問(wèn)相同的變量和對(duì)象,而且它們從同一堆中分配對(duì)象。盡管這讓線(xiàn)程之間共享信息變得更容易,但您必須小心,確保它們不會(huì)妨礙同一進(jìn)程里的其它線(xiàn)程。

Java 線(xiàn)程工具和 API看似簡(jiǎn)單。但是,編寫(xiě)有效使用線(xiàn)程的復(fù)雜程序并不十分容易。因?yàn)橛卸鄠€(gè)線(xiàn)程共存在相同的內(nèi)存空間中并共享相同的變量,所以您必須小心,確保您的線(xiàn)程不會(huì)互相干擾。

線(xiàn)程屬性

為了正確有效地使用線(xiàn)程,必須理解線(xiàn)程的各個(gè)方面并了解Java 實(shí)時(shí)系統(tǒng)。必須知道如何提供線(xiàn)程體、線(xiàn)程的生命周期、實(shí)時(shí)系統(tǒng)如 何調(diào)度線(xiàn)程、線(xiàn)程組、什么是幽靈線(xiàn)程(Demo nThread)。

線(xiàn)程體

所有的操作都發(fā)生在線(xiàn)程體中,在Java中線(xiàn)程體是從Thread類(lèi)繼承的run()方法,或?qū)崿F(xiàn)Runnable接口的類(lèi)中的run()方法。當(dāng)線(xiàn)程產(chǎn)生并初始化后,實(shí)時(shí)系統(tǒng)調(diào)用它的run()方法。run()方法內(nèi)的代碼實(shí)現(xiàn)所產(chǎn)生線(xiàn)程的行為,它是線(xiàn)程的主要部分。

線(xiàn)程狀態(tài)

附圖表示了線(xiàn)程在它的生命周期內(nèi)的任何時(shí)刻所能處的狀態(tài)以及引起狀態(tài)改變的方法。這圖并不是完整的有限狀態(tài)圖,但基本概括了線(xiàn)程中比較感興趣和普遍的方面。以下討論有關(guān)線(xiàn)程生命周期以此為據(jù)。

●新線(xiàn)程態(tài)(New Thread)

產(chǎn)生一個(gè)Thread對(duì)象就生成一個(gè)新線(xiàn)程。當(dāng)線(xiàn)程處于"新線(xiàn)程"狀態(tài)時(shí),僅僅是一個(gè)空線(xiàn)程對(duì)象,它還沒(méi)有分配到系統(tǒng)資源。因此只能啟動(dòng)或終止它。任何其他操作都會(huì)引發(fā)異常。例如,一個(gè)線(xiàn)程調(diào)用了new方法之后,并在調(diào)用start方法之前的處于新線(xiàn)程狀態(tài),可以調(diào)用start和stop方法。

●可運(yùn)行態(tài)(Runnable)

start()方法產(chǎn)生運(yùn)行線(xiàn)程所必須的資源,調(diào)度線(xiàn)程執(zhí)行,并且調(diào)用線(xiàn)程的run()方法。在這時(shí)線(xiàn)程處于可運(yùn)行態(tài)。該狀態(tài)不稱(chēng)為運(yùn)行態(tài)是因?yàn)檫@時(shí)的線(xiàn)程并不總是一直占用處理機(jī)。特別是對(duì)于只有一個(gè)處理機(jī)的PC而言,任何時(shí)刻只能有一個(gè)處于可運(yùn)行態(tài)的線(xiàn)程占用處理 機(jī)。Java通過(guò)調(diào)度來(lái)實(shí)現(xiàn)多線(xiàn)程對(duì)處理機(jī)的共享。注意,如果線(xiàn)程處于Runnable狀態(tài),它也有可能不在運(yùn)行,這是因?yàn)檫€有優(yōu)先級(jí)和調(diào)度問(wèn)題。

●阻塞/非運(yùn)行態(tài)(Not Runnable)

當(dāng)以下事件發(fā)生時(shí),線(xiàn)程進(jìn)入非運(yùn)行態(tài)。

①suspend()方法被調(diào)用;

②sleep()方法被調(diào)用;

③線(xiàn)程使用wait()來(lái)等待條件變量;

④線(xiàn)程處于I/O請(qǐng)求的等待。

●死亡態(tài)(Dead)

當(dāng)run()方法返回,或別的線(xiàn)程調(diào)用stop()方法,線(xiàn)程進(jìn)入死亡態(tài)。通常Applet使用它的stop()方法來(lái)終止它產(chǎn)生的所有線(xiàn)程。

線(xiàn)程的本操作:

派生:線(xiàn)程在進(jìn)程內(nèi)派生出來(lái),它即可由進(jìn)程派生,也可由線(xiàn)程派生。

阻塞(Block):如果一個(gè)線(xiàn)程在執(zhí)行過(guò)程中需要等待某個(gè)事件發(fā)生,則被阻塞。

激活(unblock):如果阻塞線(xiàn)程的事件發(fā)生,則該線(xiàn)程被激活并進(jìn)入就緒隊(duì)列。

調(diào)度(schedule):選擇一個(gè)就緒線(xiàn)程進(jìn)入執(zhí)行狀態(tài)。

結(jié)束(Finish):如果一個(gè)線(xiàn)程執(zhí)行結(jié)束,它的寄存器上下文以及堆棧內(nèi)容等將被釋放。

圖2 線(xiàn)程的狀態(tài)與操作

線(xiàn)程的另一個(gè)執(zhí)行特性是同步。線(xiàn)程中所使用的同步控制機(jī)制與進(jìn)程中所使用的同步控制機(jī)制相同。

線(xiàn)程優(yōu)先級(jí)

雖然我們說(shuō)線(xiàn)程是并發(fā)運(yùn)行的。然而事實(shí)常常并非如此。正如前面談到的,當(dāng)系統(tǒng)中只有一個(gè)CPU時(shí),以某種順序在單CPU情況下執(zhí)行多線(xiàn)程被稱(chēng)為調(diào)度(scheduling)。Java采用的是一種簡(jiǎn)單、固定的調(diào)度法,即固定優(yōu)先級(jí)調(diào)度。這種算法是根據(jù)處于可運(yùn)行態(tài)線(xiàn)程的相對(duì)優(yōu)先級(jí)來(lái)實(shí)行調(diào)度。當(dāng)線(xiàn)程產(chǎn)生時(shí),它繼承原線(xiàn)程的優(yōu)先級(jí)。在需要時(shí)可對(duì)優(yōu)先級(jí)進(jìn)行修改。在任何時(shí)刻,如果有多條線(xiàn)程等待運(yùn)行,系統(tǒng)選擇優(yōu)先級(jí)最高的可運(yùn)行線(xiàn)程運(yùn)行。只有當(dāng)它停止、自動(dòng)放棄、或由于某種原因成為非運(yùn)行態(tài)低優(yōu)先級(jí)的線(xiàn)程才能運(yùn)行。如果兩個(gè)線(xiàn)程具有相同的優(yōu)先級(jí),它們將被交替地運(yùn)行?!ava實(shí)時(shí)系統(tǒng)的線(xiàn)程調(diào)度算法還是強(qiáng)制性的,在任何時(shí)刻,如果一個(gè)比其他線(xiàn)程優(yōu)先級(jí)都高的線(xiàn)程的狀態(tài)變?yōu)榭蛇\(yùn)行態(tài),實(shí)時(shí)系統(tǒng)將選擇該線(xiàn)程來(lái)運(yùn)行。一個(gè)應(yīng)用程序可以通過(guò)使用線(xiàn)程中的方法setPriority(int),來(lái)設(shè)置線(xiàn)程的優(yōu)先級(jí)大小。

有線(xiàn)程進(jìn)入了就緒狀態(tài),需要有線(xiàn)程調(diào)度程序來(lái)決定何時(shí)執(zhí)行,根據(jù)優(yōu)先級(jí)來(lái)調(diào)度。

線(xiàn)程中的join()可以用來(lái)邀請(qǐng)其他線(xiàn)程先執(zhí)行(示例代碼如下):

packageorg.thread.test;publicclassJoin01implementsRunnable{publicstaticvoidmain(String[]args){for(inti=0;i

yield()告訴系統(tǒng)"把自己的CPU時(shí)間讓掉,讓其他線(xiàn)程或者自己運(yùn)行",示例代碼如下:

packageorg.thread.test;

publicclassYield01

{

publicstaticvoidmain(String[]args)

{

YieldFirstyf=newYieldFirst();

YieldSecondys=newYieldSecond();

YieldThirdyt=newYieldThird();

yf.start();ys.start();yt.start();

}

}

classYieldFirstextendsThread

{

@Overridepublicvoidrun()

{

for(inti=0;i

{

System.out.println("第一個(gè)線(xiàn)程第" (i 1) "次運(yùn)行.");//讓當(dāng)前線(xiàn)程暫停yield();

}

}

}

classYieldSecondextendsThread

{

@Overridepublicvoidrun()

{

for(inti=0;i

{

System.out.println("第二個(gè)線(xiàn)程第" (i 1) "次運(yùn)行.");//讓當(dāng)前線(xiàn)程暫停yield();

}

}

classYieldThirdextendsThread

{

@Overridepublicvoidrun(){for(inti=0;i

{

System.out.println("第三個(gè)線(xiàn)程第" (i 1) "次運(yùn)行.");//讓當(dāng)前線(xiàn)程暫停yield();

}

}

幽靈線(xiàn)程

任何一個(gè)Java線(xiàn)程都能成為幽靈線(xiàn)程。它是作為運(yùn)行于同一個(gè)進(jìn)程內(nèi)的對(duì)象和線(xiàn)程的服務(wù)提供者。例如,HotJava瀏覽器有一個(gè)稱(chēng)為" 后臺(tái)圖片閱讀器"的幽靈線(xiàn)程,它為需要圖片的對(duì)象和線(xiàn)程從文件系統(tǒng)或網(wǎng)絡(luò)讀入圖片?!∮撵`線(xiàn)程是應(yīng)用中典型的獨(dú)立線(xiàn)程。它為同一應(yīng)用中的其他對(duì)象和線(xiàn)程提供服務(wù)。幽靈線(xiàn)程的run()方法一般都是無(wú)限循環(huán),等待服務(wù)請(qǐng)求。

線(xiàn)程組

每個(gè)Java線(xiàn)程都是某個(gè)線(xiàn)程組的成員。線(xiàn)程組提供一種機(jī)制,使得多個(gè)線(xiàn)程集于一個(gè)對(duì)象內(nèi),能對(duì)它們實(shí)行整體操作。譬如,你能用一個(gè)方法調(diào)用來(lái)啟動(dòng)或掛起組內(nèi)的所有線(xiàn)程。Java線(xiàn)程組由ThreadGroup類(lèi)實(shí)現(xiàn)。

當(dāng)線(xiàn)程產(chǎn)生時(shí),可以指定線(xiàn)程組或由實(shí)時(shí)系統(tǒng)將其放入某個(gè)缺省的線(xiàn)程組內(nèi)。線(xiàn)程只能屬于一個(gè)線(xiàn)程組,并且當(dāng)線(xiàn)程產(chǎn)生后不能改變它所屬的線(xiàn)程組。

多線(xiàn)程

對(duì)于多線(xiàn)程的好處這就不多說(shuō)了。但是,它同樣也帶來(lái)了某些新的麻煩。只要在設(shè)計(jì)程序時(shí)特別小心留意,克服這些麻煩并不算太困難。在生成線(xiàn)程時(shí)必須將線(xiàn)程放在指定的線(xiàn)程組,也可以放在缺省的線(xiàn)程組中,缺省的就是生成該線(xiàn)程的線(xiàn)程所在的線(xiàn)程組。一旦一個(gè)線(xiàn)程加入了某個(gè)線(xiàn)程組,不能被移出這個(gè)組。

同步線(xiàn)程

許多線(xiàn)程在執(zhí)行中必須考慮與其他線(xiàn)程之間共享數(shù)據(jù)或協(xié)調(diào)執(zhí)行狀態(tài)。這就需要同步機(jī)制。在Java中每個(gè)對(duì)象都有一把鎖與之對(duì)應(yīng)。但Java不提供單獨(dú)的lock和unlock操作。它由高層的結(jié)構(gòu)隱式實(shí)現(xiàn),來(lái)保證操作的對(duì)應(yīng)。(然而,我們注意到Java虛擬機(jī)提供單獨(dú)的monito renter和monitorexit指令來(lái)實(shí)現(xiàn)lock和

unlock操作。) synchronized語(yǔ)句計(jì)算一個(gè)對(duì)象引用,試圖對(duì)該對(duì)象完成鎖操作,并且在完成鎖操作前停止處理。當(dāng)鎖操作完成synchronized語(yǔ)句體得到執(zhí)行。當(dāng)語(yǔ)句體執(zhí)行完畢(無(wú)論正常或異常),解鎖操作自動(dòng)完成。作為面向?qū)ο蟮恼Z(yǔ)言,synchronized經(jīng)常與方法連用。一種比較好的辦法是,如果某個(gè)變量由一個(gè)線(xiàn)程賦值并由別的線(xiàn)程引用或賦值,那么所有對(duì)該變量的訪問(wèn)都必須在某個(gè)synchromized語(yǔ)句或synchronized方法內(nèi)。

在此假設(shè)一種情況:線(xiàn)程1與線(xiàn)程2都要訪問(wèn)某個(gè)數(shù)據(jù)區(qū),并且要求線(xiàn)程1的訪問(wèn)先于線(xiàn)程2,則這時(shí)僅用synchronized是不能解決問(wèn)題的。這在Unix或Windows NT中可用Simaphore來(lái)實(shí)現(xiàn)。而Java并不提供。在Java中提供的是wait()和notify()機(jī)制。使用如下:

synchronizedmethod_1(/*……*/){//calledbythread1.//accessdataareaavailable=true;notify();}synchronizedmethod_2(/*……*/){//calledbythread2.while(!available)try{wait();//waitfornotify().}catch(InterruptedExceptione){}//accessdataarea}

其中available是類(lèi)成員變量,置初值為false。

如果在method-2中檢查available為假,則調(diào)用wait()。wait()的作用是使線(xiàn)程2進(jìn)入非運(yùn)行態(tài),并且解鎖。在這種情況下,method-1可以被線(xiàn)程1調(diào)用。當(dāng)執(zhí)行notify()后。線(xiàn)程2由非運(yùn)行態(tài)轉(zhuǎn)變?yōu)榭蛇\(yùn)行態(tài)。當(dāng)method-1調(diào)用返回后。線(xiàn)程2可重新對(duì)該對(duì)象加鎖,加鎖成功后執(zhí)行wait()返回后的指令。這種機(jī)制也能適用于其他更復(fù)雜的情況。

死鎖

如果程序中有幾個(gè)競(jìng)爭(zhēng)資源的并發(fā)線(xiàn)程,那么保證均衡是很重要的。系統(tǒng)均衡是指每個(gè)線(xiàn)程在執(zhí)行過(guò)程中都能充分訪問(wèn)有限的資源。系統(tǒng)中沒(méi)有餓死和死鎖的線(xiàn)程。Java并不提供對(duì)死鎖的檢測(cè)機(jī)制。對(duì)大多數(shù)的Java程序員來(lái)說(shuō)防止死鎖是一種較好的選擇。最簡(jiǎn)單的防止死鎖的方法是對(duì)競(jìng)爭(zhēng)的資源引入序號(hào),如果一個(gè)線(xiàn)程需要幾個(gè)資源,那么它必須先得到小序號(hào)的資源,再申請(qǐng)大序號(hào)的資源。

優(yōu)化

Java的多線(xiàn)程安全是基于Lock機(jī)制實(shí)現(xiàn)的,而Lock的性能往往不如人意。原因是,monitorenter與monitorexit這兩個(gè)控制多線(xiàn)程同步的bytecode原語(yǔ),是JVM依賴(lài)操作系統(tǒng)互斥(mutex)來(lái)實(shí)現(xiàn)的。而互斥是一種會(huì)導(dǎo)致線(xiàn)程掛起,并在較短的時(shí)間內(nèi)又需要重新調(diào)度回原線(xiàn)程的,較為消耗資源的操作。所以需要進(jìn)行對(duì)線(xiàn)程進(jìn)行優(yōu)化,提高效率。

輕量級(jí)鎖

輕量級(jí)鎖(Lightweight Locking)是從Java6開(kāi)始引入的概念,本意是為了減少多線(xiàn)程進(jìn)入互斥的幾率,并不是要替代互斥。它利用了CPU原語(yǔ)Compare-And-Swap(CAS,匯編指令CMPXCHG),嘗試在進(jìn)入互斥前,進(jìn)行補(bǔ)救。下面將詳細(xì)介紹JVM如何利用CAS,實(shí)現(xiàn)輕量級(jí)鎖。

Java Object Model中定義,Object Header是一個(gè)2字(1 word = 4 byte)長(zhǎng)度的存儲(chǔ)區(qū)域。第一個(gè)字長(zhǎng)度的區(qū)域用來(lái)標(biāo)記同步,GC以及hash code等,官方稱(chēng)之為 mark word。第二個(gè)字長(zhǎng)度的區(qū)域是指向到對(duì)象的Class。在2個(gè)word中,mark word是輕量級(jí)鎖實(shí)現(xiàn)的關(guān)鍵,其結(jié)構(gòu)見(jiàn)右表。

從表中可以看到,state為lightweight locked的那行即為輕量級(jí)鎖標(biāo)記。bitfieds名為指向lock record的指針,這里的lock record,其實(shí)是一塊分配在線(xiàn)程堆棧上的空間區(qū)域。用于CAS前,拷貝object上的mark word。第三項(xiàng)是重量級(jí)鎖標(biāo)記。后面的狀態(tài)單詞很有趣,inflated,譯為膨脹,在這里意思其實(shí)是鎖已升級(jí)到OS-level。一般我們只關(guān)注第二和第三項(xiàng)即可。lock,unlock與mark word之間的聯(lián)系如右圖所示。在圖中,提到了拷貝object mark word,由于脫離了原始mark word,官方將它冠以displaced前綴,即displaced mark word(置換標(biāo)記字)。這個(gè)displaced mark word是整個(gè)輕量級(jí)鎖實(shí)現(xiàn)的關(guān)鍵,在CAS中的compare就需要用它作為條件。

在拷貝完object mark word之后,JVM做了一步交換指針的操作,即流程中第一個(gè)橙色矩形框內(nèi)容所述。將object mark word里的輕量級(jí)鎖指針指向lock record所在的stack指針,作用是讓其他線(xiàn)程知道,該object monitor已被占用。lock record里的owner指針指向object mark word的作用是為了在接下里的運(yùn)行過(guò)程中,識(shí)別哪個(gè)對(duì)象被鎖住了。

最后一步unlock中,我們發(fā)現(xiàn),JVM同樣使用了CAS來(lái)驗(yàn)證object mark word在持有鎖到釋放鎖之間,有無(wú)被其他線(xiàn)程訪問(wèn)。如果其他線(xiàn)程在持有鎖這段時(shí)間里,嘗試獲取過(guò)鎖,則可能自身被掛起,而mark word的重量級(jí)鎖指針也會(huì)被相應(yīng)修改。此時(shí),unlock后就需要喚醒被掛起的線(xiàn)程。

偏向鎖

Java偏向鎖(Biased Locking)是Java 6引入的一項(xiàng)多線(xiàn)程優(yōu)化。它通過(guò)消除資源無(wú)競(jìng)爭(zhēng)情況下的同步原語(yǔ),進(jìn)一步提高了程序的運(yùn)行性能。它與輕量級(jí)鎖的區(qū)別在于,輕量級(jí)鎖是通過(guò)CAS來(lái)避免進(jìn)入開(kāi)銷(xiāo)較大的互斥操作,而偏向鎖是在無(wú)競(jìng)爭(zhēng)場(chǎng)景下完全消除同步,連CAS也不執(zhí)行(CAS本身仍舊是一種操作系統(tǒng)同步原語(yǔ),始終要在JVM與OS之間來(lái)回,有一定的開(kāi)銷(xiāo))。所謂的無(wú)競(jìng)爭(zhēng)場(chǎng)景,就是單線(xiàn)程訪問(wèn)帶同步的資源或方法。

偏向鎖,顧名思義,它會(huì)偏向于第一個(gè)訪問(wèn)鎖的線(xiàn)程,如果在接下來(lái)的運(yùn)行過(guò)程中,該鎖沒(méi)有被其他的線(xiàn)程訪問(wèn),則持有偏向鎖的線(xiàn)程將永遠(yuǎn)不需要觸發(fā)同步。如果在運(yùn)行過(guò)程中,遇到了其他線(xiàn)程搶占鎖,則持有偏向鎖的線(xiàn)程會(huì)被掛起,JVM會(huì)嘗試消除它身上的偏向鎖,將鎖恢復(fù)到標(biāo)準(zhǔn)的輕量級(jí)鎖。(偏向鎖只能在單線(xiàn)程下起作用)。

偏向模式和非偏向模式,在mark word表中,主要體現(xiàn)在thread ID字段是否為空。

掛起持有偏向鎖的線(xiàn)程,這步操作類(lèi)似GC的pause,但不同之處是,它只掛起持有偏向鎖的線(xiàn)程(非當(dāng)前線(xiàn)程)。

在搶占模式的橙色區(qū)域說(shuō)明中有提到,指向當(dāng)前堆棧中最近的一個(gè)lock record(在輕量級(jí)鎖中,lock record是進(jìn)入鎖前會(huì)在stack上創(chuàng)建的一份內(nèi)存空間)。這里提到的最近的一個(gè)lock record,其實(shí)就是當(dāng)前鎖所在的stack frame上分配的lock record。整個(gè)步驟是從偏向鎖恢復(fù)到輕量級(jí)鎖的過(guò)程。

偏向鎖也會(huì)帶來(lái)額外開(kāi)銷(xiāo)。在JDK6中,偏向鎖是默認(rèn)啟用的。它提高了單線(xiàn)程訪問(wèn)同步資源的性能。

但試想一下,如果你的同步資源或代碼一直都是多線(xiàn)程訪問(wèn)的,那么消除偏向鎖這一步驟對(duì)你來(lái)說(shuō)就是多余的。事實(shí)上,消除偏向鎖的開(kāi)銷(xiāo)還是蠻大的。所以在你非常熟悉自己的代碼前提下,大可禁用偏向鎖 -XX:-UseBiasedLocking。

分類(lèi)

線(xiàn)程有兩個(gè)基本類(lèi)型:

用戶(hù)級(jí)線(xiàn)程:管理過(guò)程全部由用戶(hù)程序完成,操作系統(tǒng)內(nèi)核心只對(duì)進(jìn)程進(jìn)行管理。

系統(tǒng)級(jí)線(xiàn)程(核心級(jí)線(xiàn)程):由操作系統(tǒng)內(nèi)核進(jìn)行管理。操作系統(tǒng)內(nèi)核給應(yīng)用程序提供相應(yīng)的系統(tǒng)調(diào)用和應(yīng)用程序接口API,以使用戶(hù)程序可以創(chuàng)建、執(zhí)行、撤消線(xiàn)程。

舉例UNIX International 線(xiàn)程

UNIX International 線(xiàn)程的頭文件是 ,僅適用于Sun Solaris操作系統(tǒng)。所以UNIX International線(xiàn)程也常被俗稱(chēng)為Solaris線(xiàn)程。

1.創(chuàng)建線(xiàn)程

intthr_create(void*stack_base,size_tstack_size,void*(*start_routine)(void*),void*arg,longflags,thread_t*new_thr);

2.等待線(xiàn)程

intthr_join(thread_twait_for,thread_t*dead,void**status);

3.掛起線(xiàn)程

intthr_suspend(thread_tthr);

4.繼續(xù)線(xiàn)程

intthr_continue(thread_tthr);

5.退出線(xiàn)程

voidthr_exit(void*status);

6.返回當(dāng)前線(xiàn)程的線(xiàn)程標(biāo)識(shí)符

thread_tthr_self(void);POSIX線(xiàn)程

POSIX線(xiàn)程(Pthreads)的頭文件是,適用于類(lèi)Unix操作系統(tǒng)。Windows操作系統(tǒng)并沒(méi)有對(duì)POSIX線(xiàn)程提供原生的支持庫(kù)。不過(guò)Win32的POSIX線(xiàn)程庫(kù)的一些實(shí)現(xiàn)也還是有的,例如pthreads-w32 。

1.創(chuàng)建線(xiàn)程

intpthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*),void*arg);

2.等待線(xiàn)程

intpthread_join(pthread_tthread,void**retval);

3.退出線(xiàn)程

voidpthread_exit(void*retval);

4.返回當(dāng)前線(xiàn)程的線(xiàn)程標(biāo)識(shí)符

pthread_tpthread_self(void);

5.線(xiàn)程取消

intpthread_cancel(pthread_tthread);Win32線(xiàn)程

Win32線(xiàn)程的頭文件是,適用于Windows操作系統(tǒng)。

1.創(chuàng)建線(xiàn)程

HANDLEWINAPICreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes,SIZE_TdwStackSize,LPTHREAD_START_ROUTINElpStartAddress,LPVOIDlpParameter,DWORDdwCreationFlags,LPDWORDlpThreadId);

2.結(jié)束本線(xiàn)程

VOIDWINAPIExitThread(DWORDdwExitCode);

3.掛起指定的線(xiàn)程

DWORDWINAPISuspendThread(HANDLEhThread);

4.恢復(fù)指定線(xiàn)程運(yùn)行

DWORDWINAPIResumeThread(HANDLEhThread);

5.等待線(xiàn)程運(yùn)行完畢

DWORDWINAPIWaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds);

6.返回當(dāng)前線(xiàn)程的線(xiàn)程標(biāo)識(shí)符

DWORDWINAPIGetCurrentThreadId(void);

7.返回當(dāng)前線(xiàn)程的線(xiàn)程句柄

HANDLEWINAPIGetCurrentThread(void);C 11 線(xiàn)程

C 11 線(xiàn)程的頭文件是。

  1. 創(chuàng)建線(xiàn)程std::thread::thread(Function&& f, Args&&... args);

  2. 等待線(xiàn)程結(jié)束std::thread::join();

  3. 脫離線(xiàn)程控制std::thread::detach();

  4. 交換線(xiàn)程std::thread::swap( thread& other );

C 11 線(xiàn)程

C11線(xiàn)程的頭文件是。

C11線(xiàn)程僅僅是個(gè)“建議標(biāo)準(zhǔn)”,也就是說(shuō)100%遵守C11標(biāo)準(zhǔn)的C編譯器是可以不支持C11線(xiàn)程的。根據(jù)C11標(biāo)準(zhǔn)的規(guī)定,只要編譯器預(yù)定義了__STDC_NO_THREADS__宏,就可以沒(méi)有頭文件,自然也就也沒(méi)有下列函數(shù)。

1.創(chuàng)建線(xiàn)程

intthrd_create(thrd_t*thr,thrd_start_tfunc,void*arg);

2.結(jié)束本線(xiàn)程

_Noreturnvoidthrd_exit(intres);

3.等待線(xiàn)程運(yùn)行完畢

intthrd_join(thrd_tthr,int*res);

4.返回當(dāng)前線(xiàn)程的線(xiàn)程標(biāo)識(shí)符

thrd_tthrd_current();Java線(xiàn)程

1)最簡(jiǎn)單的情況是,Thread/Runnable的run()方法運(yùn)行完畢,自行終止。

2)對(duì)于更復(fù)雜的情況,比如有循環(huán),則可以增加終止標(biāo)記變量和任務(wù)終止的檢查點(diǎn)。

3)最常見(jiàn)的情況,也是為了解決阻塞不能執(zhí)行檢查點(diǎn)的問(wèn)題,用中斷來(lái)結(jié)束線(xiàn)程,但中斷只是請(qǐng)求,并不能完全保證線(xiàn)程被終止,需要執(zhí)行線(xiàn)程協(xié)同處理。

4)IO阻塞和等鎖情況下需要通過(guò)特殊方式進(jìn)行處理。

5)使用Future類(lèi)的cancel()方法調(diào)用。

6)調(diào)用線(xiàn)程池執(zhí)行器的shutdown()和shutdownNow()方法。

7)守護(hù)線(xiàn)程會(huì)在非守護(hù)線(xiàn)程都結(jié)束時(shí)自動(dòng)終止。

8)Thread的stop()方法,但已不推薦使用。

線(xiàn)程的組成

1)一組代表處理器狀態(tài)的CPU寄存器中的內(nèi)容

2)兩個(gè)棧,一個(gè)用于當(dāng)線(xiàn)程在內(nèi)核模式下執(zhí)行的時(shí)候,另一個(gè)用于線(xiàn)程在用戶(hù)模式下執(zhí)行的時(shí)候

3)一個(gè)被稱(chēng)為線(xiàn)程局部存儲(chǔ)器(TLS,thread-local storage)的私有儲(chǔ)存區(qū)域,各個(gè)子系統(tǒng)、運(yùn)行庫(kù)和DLL都會(huì)用到該儲(chǔ)存區(qū)域

4)一個(gè)被稱(chēng)為線(xiàn)程ID(thread ID,線(xiàn)程標(biāo)識(shí)符)的唯一標(biāo)識(shí)符(在內(nèi)部也被稱(chēng)為客戶(hù)ID——進(jìn)程ID和線(xiàn)程ID是在同一個(gè)名字空間中生產(chǎn)的,所以它們永遠(yuǎn) 不會(huì)重疊)

5)有時(shí)候線(xiàn)程也有它們自己的安全環(huán)境,如果多線(xiàn)程服務(wù)器應(yīng)用程序要模仿其客戶(hù)的安全環(huán)境,則往往可以利用線(xiàn)程的安全環(huán)境

1.服務(wù)器中的文件管理或通信控制

2.前后臺(tái)處理

3.異步處理

守護(hù)線(xiàn)程是特殊的線(xiàn)程,一般用于在后臺(tái)為其他線(xiàn)程提供服務(wù).

Java中,isDaemon():判斷一個(gè)線(xiàn)程是否為守護(hù)線(xiàn)程.

Java中,setDaemon():設(shè)置一個(gè)線(xiàn)程為守護(hù)線(xiàn)程.

C# 守護(hù)線(xiàn)程

類(lèi)1:守護(hù)線(xiàn)程類(lèi)

/**
* 本線(xiàn)程設(shè)置了一個(gè)超時(shí)時(shí)間
* 該線(xiàn)程開(kāi)始運(yùn)行后,經(jīng)過(guò)指定超時(shí)時(shí)間,
* 該線(xiàn)程會(huì)拋出一個(gè)未檢查異常通知調(diào)用該線(xiàn)程的程序超時(shí)
* 在超時(shí)結(jié)束前可以調(diào)用該類(lèi)的cancel方法取消計(jì)時(shí)
* @author solonote
*/public class TimeoutThread extends Thread{
/**
* 計(jì)時(shí)器超時(shí)時(shí)間
*/
private long timeout;
/**
* 計(jì)時(shí)是否被取消
*/
private boolean isCanceled = false;
/**
* 當(dāng)計(jì)時(shí)器超時(shí)時(shí)拋出的異常
*/
private TimeoutException timeoutException;
/**
* 構(gòu)造器
* @param timeout 指定超時(shí)的時(shí)間
*/
public TimeoutThread(long timeout,TimeoutException timeoutErr) {
super();
this.timeout = timeout;
this.timeoutException = timeoutErr;
//設(shè)置本線(xiàn)程為守護(hù)線(xiàn)程
this.setDaemon(true);
}
/**
* 取消計(jì)時(shí)
*/
public synchronized void cancel()
{
isCanceled = true;
}
/**
* 啟動(dòng)超時(shí)計(jì)時(shí)器
*/
public void run()
{
try {
Thread.sleep(timeout);
if(!isCanceled)
throw timeoutException;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

線(xiàn)程文獻(xiàn)

多態(tài)并行處理器中的線(xiàn)程管理器設(shè)計(jì) 多態(tài)并行處理器中的線(xiàn)程管理器設(shè)計(jì)

格式:pdf

大?。?span id="cjtyiat" class="single-tag-height">466KB

頁(yè)數(shù): 未知

評(píng)分: 4.8

基于多態(tài)并行處理器提出了一種硬件線(xiàn)程管理器,支持MIMD模式8個(gè)線(xiàn)程管理操作和SIMD模式SC控制器統(tǒng)一管理兩種工作模式,實(shí)現(xiàn)了線(xiàn)程級(jí)并行計(jì)算;可以監(jiān)測(cè)各個(gè)線(xiàn)程的工作情況以及近鄰?fù)ㄐ偶拇嫫骱吐酚善鞯臓顟B(tài);能夠在通信時(shí)停止、切換、啟動(dòng)線(xiàn)程,記錄每個(gè)線(xiàn)程的工作狀態(tài),同時(shí)避免了因數(shù)據(jù)阻塞帶來(lái)的等待問(wèn)題,能夠最大程度地提高單個(gè)處理器的執(zhí)行效率。

立即下載
濕能空調(diào)測(cè)控軟件的多線(xiàn)程設(shè)計(jì) 濕能空調(diào)測(cè)控軟件的多線(xiàn)程設(shè)計(jì)

格式:pdf

大小:466KB

頁(yè)數(shù): 4頁(yè)

評(píng)分: 4.5

濕能空調(diào)機(jī)組是一種可提供全新風(fēng)的新型空調(diào)設(shè)備。目前濕能空調(diào)機(jī)組的性能檢測(cè)系統(tǒng)已開(kāi)發(fā)成功。介紹了性能檢測(cè)系統(tǒng)的體系結(jié)構(gòu)。測(cè)控軟件采用基于Delphi平臺(tái)的多線(xiàn)程模式,并實(shí)現(xiàn)相應(yīng)的功能。運(yùn)行結(jié)果表明,檢測(cè)系統(tǒng)的測(cè)試精度達(dá)到了國(guó)家標(biāo)準(zhǔn)的要求,測(cè)控軟件的性能完善,工作可靠。

立即下載

線(xiàn)程池線(xiàn)程池

//線(xiàn)程池示例
usingSystem;
usingSystem.Threading;publicclassTest
{
//存放要計(jì)算的數(shù)值的字段
staticdoublenumber1=-1;
staticdoublenumber2=-1;publicstaticvoidMain()
{
//獲取線(xiàn)程池的最大線(xiàn)程數(shù)和維護(hù)的最小空閑線(xiàn)程數(shù)
intmaxThreadNum,minThreadNum;
intportThreadNum;

ThreadPool.GetMaxThreads(outmaxThreadNum,outportThreadNum);
ThreadPool.GetMinThreads(outminThreadNum,outportThreadNum);
Console.WriteLine("最大線(xiàn)程數(shù):{0}",maxThreadNum);
Console.WriteLine("最小線(xiàn)程數(shù):{0}",minThreadNum);

//函數(shù)變量值
intx=15600;
//啟動(dòng)第一個(gè)任務(wù):計(jì)算x的8次方
Console.WriteLine("啟動(dòng)第一個(gè)任務(wù):計(jì)算{0}的8次方。",x);
ThreadPool.QueueUserWorkItem(newWaitCallback(TaskProc1),x);

//啟動(dòng)第二個(gè)任務(wù):計(jì)算x的8次方根
Console.WriteLine("啟動(dòng)第二個(gè)任務(wù):計(jì)算{0}的8次方根。",x);
ThreadPool.QueueUserWorkItem(newWaitCallback(TaskProc2),x);

//等待,直到兩個(gè)數(shù)值都完成計(jì)算
while(number1==-1||number2==-1);
//打印計(jì)算結(jié)果
Console.WriteLine("y({0})={1}",x,number1 number2);
Console.Read();
}

//啟動(dòng)第一個(gè)任務(wù):計(jì)算x的8次方
staticvoidTaskProc1(objecto)
{
number1=Math.Pow(Convert.ToDouble(o),8);
}

//啟動(dòng)第二個(gè)任務(wù):計(jì)算x的8次方根
staticvoidTaskProc2(objecto)
{
number2=Math.Pow(Convert.ToDouble(o),1.0/8.0);
}
}

線(xiàn)程池池結(jié)構(gòu)

[HostProtection(SecurityAction.LinkDemand,Synchronization=true,ExternalThreading=true)]publicstaticclassThreadPool
{
[Obsolete("ThreadPool.BindHandle(IntPtr)hasbeendeprecated.PleaseuseThreadPool.BindHandle(SafeHandle)instead.",false),SecurityPermission(SecurityAction.Demand,Flags=SecurityPermissionFlag.UnmanagedCode)]
publicstaticboolBindHandle(IntPtrosHandle)
{
if(osHandle==null){thrownewArgumentNullException("osHandle");}
boolflag=false;
boolsuccess=false;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
osHandle.DangerousAddRef(refsuccess);
flag=BindIOCompletionCallbackNative(osHandle.DangerousGetHandle());
}
finally
{
if(success)
osHandle.DangerousRelease();
}
returnflag;
}

線(xiàn)程池(英語(yǔ):thread pool):一種線(xiàn)程使用模式。線(xiàn)程過(guò)多會(huì)帶來(lái)調(diào)度開(kāi)銷(xiāo),進(jìn)而影響緩存局部性和整體性能。而線(xiàn)程池維護(hù)著多個(gè)線(xiàn)程,等待著監(jiān)督管理者分配可并發(fā)執(zhí)行的任務(wù)。這避免了在處理短時(shí)間任務(wù)時(shí)創(chuàng)建與銷(xiāo)毀線(xiàn)程的代價(jià)。線(xiàn)程池不僅能夠保證內(nèi)核的充分利用,還能防止過(guò)分調(diào)度??捎镁€(xiàn)程數(shù)量應(yīng)該取決于可用的并發(fā)處理器、處理器內(nèi)核、內(nèi)存、網(wǎng)絡(luò)sockets等的數(shù)量。 例如,線(xiàn)程數(shù)一般取cpu數(shù)量 2比較合適,線(xiàn)程數(shù)過(guò)多會(huì)導(dǎo)致額外的線(xiàn)程切換開(kāi)銷(xiāo)。

任務(wù)調(diào)度以執(zhí)行線(xiàn)程的常見(jiàn)方法是使用同步隊(duì)列,稱(chēng)作任務(wù)隊(duì)列。池中的線(xiàn)程等待隊(duì)列中的任務(wù),并把執(zhí)行完的任務(wù)放入完成隊(duì)列中。

線(xiàn)程池模式一般分為兩種:HS/HA半同步/半異步模式、L/F領(lǐng)導(dǎo)者與跟隨者模式。

  • 半同步/半異步模式又稱(chēng)為生產(chǎn)者消費(fèi)者模式,是比較常見(jiàn)的實(shí)現(xiàn)方式,比較簡(jiǎn)單。分為同步層、隊(duì)列層、異步層三層。同步層的主線(xiàn)程處理工作任務(wù)并存入工作隊(duì)列,工作線(xiàn)程從工作隊(duì)列取出任務(wù)進(jìn)行處理,如果工作隊(duì)列為空,則取不到任務(wù)的工作線(xiàn)程進(jìn)入掛起狀態(tài)。由于線(xiàn)程間有數(shù)據(jù)通信,因此不適于大數(shù)據(jù)量交換的場(chǎng)合。

  • 領(lǐng)導(dǎo)者跟隨者模式,在線(xiàn)程池中的線(xiàn)程可處在3種狀態(tài)之一:領(lǐng)導(dǎo)者leader、追隨者follower或工作者processor。任何時(shí)刻線(xiàn)程池只有一個(gè)領(lǐng)導(dǎo)者線(xiàn)程。事件到達(dá)時(shí),領(lǐng)導(dǎo)者線(xiàn)程負(fù)責(zé)消息分離,并從處于追隨者線(xiàn)程中選出一個(gè)來(lái)當(dāng)繼任領(lǐng)導(dǎo)者,然后將自身設(shè)置為工作者狀態(tài)去處置該事件。處理完畢后工作者線(xiàn)程將自身的狀態(tài)置為追隨者。這一模式實(shí)現(xiàn)復(fù)雜,但避免了線(xiàn)程間交換任務(wù)數(shù)據(jù),提高了CPU cache相似性。在ACE(Adaptive Communication Environment)中,提供了領(lǐng)導(dǎo)者跟隨者模式實(shí)現(xiàn)。

線(xiàn)程池的伸縮性對(duì)性能有較大的影響。

  • 創(chuàng)建太多線(xiàn)程,將會(huì)浪費(fèi)一定的資源,有些線(xiàn)程未被充分使用。

  • 銷(xiāo)毀太多線(xiàn)程,將導(dǎo)致之后浪費(fèi)時(shí)間再次創(chuàng)建它們。

  • 創(chuàng)建線(xiàn)程太慢,將會(huì)導(dǎo)致長(zhǎng)時(shí)間的等待,性能變差。

  • 銷(xiāo)毀線(xiàn)程太慢,導(dǎo)致其它線(xiàn)程資源饑餓。

應(yīng)用程序可以有多個(gè)線(xiàn)程,這些線(xiàn)程在休眠狀態(tài)中需要耗費(fèi)大量時(shí)間來(lái)等待事件發(fā)生。其他線(xiàn)程可能進(jìn)入睡眠狀態(tài),并且僅定期被喚醒以輪循更改或更新?tīng)顟B(tài)信息,然后再次進(jìn)入休眠狀態(tài)。為了簡(jiǎn)化對(duì)這些線(xiàn)程的管理,.NET框架為每個(gè)進(jìn)程提供了一個(gè)線(xiàn)程池,一個(gè)線(xiàn)程池有若干個(gè)等待操作狀態(tài),當(dāng)一個(gè)等待操作完成時(shí),線(xiàn)程池中的輔助線(xiàn)程會(huì)執(zhí)行回調(diào)函數(shù)。線(xiàn)程池中的線(xiàn)程由系統(tǒng)管理,程序員不需要費(fèi)力于線(xiàn)程管理,可以集中精力處理應(yīng)用程序任務(wù)。

線(xiàn)程相關(guān)推薦
  • 相關(guān)百科
  • 相關(guān)知識(shí)
  • 相關(guān)專(zhuān)欄

最新詞條

安徽省政采項(xiàng)目管理咨詢(xún)有限公司 數(shù)字景楓科技發(fā)展(南京)有限公司 懷化市人民政府電子政務(wù)管理辦公室 河北省高速公路京德臨時(shí)籌建處 中石化華東石油工程有限公司工程技術(shù)分公司 手持無(wú)線(xiàn)POS機(jī) 廣東合正采購(gòu)招標(biāo)有限公司 上海城建信息科技有限公司 甘肅鑫禾國(guó)際招標(biāo)有限公司 燒結(jié)金屬材料 齒輪計(jì)量泵 廣州采陽(yáng)招標(biāo)代理有限公司河源分公司 高鋁碳化硅磚 博洛尼智能科技(青島)有限公司 燒結(jié)剛玉磚 深圳市東海國(guó)際招標(biāo)有限公司 搭建香蕉育苗大棚 SF計(jì)量單位 福建省中億通招標(biāo)咨詢(xún)有限公司 泛海三江 威海鼠尾草 Excel 數(shù)據(jù)處理與分析應(yīng)用大全 廣東國(guó)咨招標(biāo)有限公司 甘肅中泰博瑞工程項(xiàng)目管理咨詢(xún)有限公司 拆邊機(jī) 山東創(chuàng)盈項(xiàng)目管理有限公司 當(dāng)代建筑大師 廣西北纜電纜有限公司 大山檳榔 上海地鐵維護(hù)保障有限公司通號(hào)分公司 舌花雛菊 甘肅中維國(guó)際招標(biāo)有限公司 華潤(rùn)燃?xì)猓ㄉ虾#┯邢薰? 湖北鑫宇陽(yáng)光工程咨詢(xún)有限公司 GB8163標(biāo)準(zhǔn)無(wú)縫鋼管 中國(guó)石油煉化工程建設(shè)項(xiàng)目部 韶關(guān)市優(yōu)采招標(biāo)代理有限公司 莎草目 電梯平層準(zhǔn)確度 建設(shè)部關(guān)于開(kāi)展城市規(guī)劃動(dòng)態(tài)監(jiān)測(cè)工作的通知 廣州利好來(lái)電氣有限公司 四川中澤盛世招標(biāo)代理有限公司