首頁 >Java >java教程 >java學習:什麼是執行緒?最詳細的解釋

java學習:什麼是執行緒?最詳細的解釋

php是最好的语言
php是最好的语言原創
2018-08-06 16:44:401930瀏覽

什麼是執行緒:有時也被變成輕量級進程,是程式執行流的最小單元。

一個標準的執行緒是由執行緒ID,目前指令指標(PC)、暫存器集合和堆疊組成。

一個行程是由一個到多個執行緒組成,各個執行緒之間共享程式的記憶體空間(包括程式碼段,資料段的堆等)及一些行程級的資源(如開啟檔案和訊號)

多個執行緒可以互不干擾的並發執行,並共享進程的全域變數和堆的資料;

執行緒的存取權

執行緒的存取權限非常自由,可以存取進程記憶體裡的所有資料;

java學習:什麼是執行緒?最詳細的解釋

執行緒調度與優先權

單處理器對應多執行緒:作業系統讓這些多執行緒輪流執行,每次只執行一小段時間(通常是幾十秒),這樣每個執行緒「看起來」就像是在同時執行;這樣的一個處理器上不斷切換執行緒的操作成為「執行緒調度」

執行緒調度中的三種狀態:

1):執行,此時執行緒正在執行

#(2# ):就緒,此時執行緒可以立即執行,但CPU已被佔用

#3):等待,此時執行緒正在等待某一事件發生,無法執行

每當一個程式離開運行狀態,調度系統就會選擇一個就緒的執行緒執行;一個在等待狀態的執行緒事件發生以後進入就緒狀態。

java學習:什麼是執行緒?最詳細的解釋

在優先權排程的情況下,執行緒優先權的改變一般有三種方式:

使用者指定優先權;

根據進入等待狀態的頻繁程度提升或降低優先權;

長時間無法執行而被提升優先權;

Linux的多執行緒

在Linux下,可以用以下三個方法建立一個新的任務:

(1)fork:複製目前進程

(2)exec:使用新的可執行映像覆寫目前可執行映像

(3)clone:建立子進程,並從指定位置開始執行;

fork:

pid_t pid;

if(pid==fork()){…}

在fork呼叫以後,新的任務啟動並和本任務一起從fork函數返回,但不同的是本任務的fork將返回新任務的pid,而新任務的fork將返回0;

fork產生新任務的速度非常快,因為fork不複製原任務的記憶體空間,而是和原任務一起共享一個寫時拷貝的記憶體空間;

所謂#寫時拷貝:指的是兩個任務可以同時自由地讀取內存,但任一個任務試圖對內存進行修改時,內存就會複製一份提供給修改方單獨使用,以免影響到其他的任務使用;

java學習:什麼是執行緒?最詳細的解釋

 fork只能夠產生本任務的鏡像,因此必須使用exec配合才能啟動別的新任務,exec可以用新的可執行映像取代目前的可執行映像,因此在fork產生了一個新任務之後,新任務可以呼叫exec來執行新的可執行檔;

頭檔都定義在pthread.h中

建立一個執行緒:#include

int pthread_create (pthread_t *thread,const pthread_attr_t* attr,void*(*start_routine)(void*),void*arg)

thread參數是新執行緒的識別符,後續的pthread_*函數透過它來引用新線程;

attr參數用來設定新執行緒的屬性,給它傳遞NULL表示使用預設執行緒屬性;

Start_routine 和arg參數分別制定新執行緒將執行的函數及參數;

pthread_create成功時返回0,失敗時返回錯誤碼;

結束一個執行緒:void pthread_exit(void *retval)

函數透過retval參數向執行緒的回收者傳遞其退出訊息;

執行緒安全性:

多執行緒程式處於一個多變的環境當中,可存取的全域變數和堆疊資料都可能隨時被其他的執行緒改變;

手段:同步與鎖定

原子的:單一指令運算稱為原子的,無論如何,單一指令的執行是不會被打斷的;

為了避免多個執行緒同時讀寫一個資料而產生不可預料的後果,我們要將各個執行緒對同一個資料的存取同步(所謂同步,就是在一個執行緒存取資料未結束時,其他執行緒不得對同一個資料進行存取),因此,對資料的存取被原子化;

同步的常見方法:(信號量、互斥量、臨界區,讀寫鎖定、條件變數)

鎖定:每個執行緒在存取資料或資源時首先試圖取得鎖,並在存取結束後釋放鎖定;

信號量:執行緒存取資源的時候先取得訊號量;

操作如下:

(1)將訊號量的值減1;

(2)如果訊號量的值小於0,則進入等待狀態;否則繼續執行;

存取完資源之後,執行緒釋放信號量;

(3)將信號量的值加1;

(4)如果信號量的值小於1,喚醒一個等待中的執行緒;

互斥量&&訊號量

##相同:資源僅同時允許一個線程訪問;

異:信號量在整個系統中,可以被任意線程獲取並釋放,也就是說,同一個信號量可以被系統中的一個線程獲取後,另一個線程釋放;

而互斥量要求哪個線程獲取了互斥量,哪個線程就要負責釋放這個鎖,其他線程越俎代庖去釋放互斥量是無效的;

#臨界區:是比互斥量更嚴格的同步手段

把臨界區的鎖的取得稱為進入臨界區;

而把鎖的釋放稱為離開臨界區。

區別(與信號量和互斥量)

互斥量和信號量在系統的任何進程裡都是可見的;

也就是說一個進程創建了一個互斥量或信號量,另一個進程試圖去獲取該鎖是合法的;

臨界區的作用範圍僅限於本進程,其他的進程無法取得該鎖定

讀取寫入鎖定:

兩種方法:共享的  獨佔的

java學習:什麼是執行緒?最詳細的解釋

當鎖定出於自由狀態時,試圖以任何一種方式取得鎖都能成功,並將鎖置於對應的狀態;(如上圖)

條件變數:作為同步的一種手段,作用類似於一個柵欄;

對於條件變量,執行緒有兩種操作:

(1)首先執行緒可以等待條件變量,一個條件變數可以被多個執行緒等待;

( 2)執行緒可以喚醒條件變量,此時某個或所有等待此條件變數的執行緒都會被喚醒並繼續支援;

#(也就是說,使用條件變數可以讓許多現車鞥一起等待某個事件的發生,當事件發生時,所有執行緒可以一起恢復執行)。

相關文章:

什麼是行程(process)?什麼是執行緒?

基於java學習中多執行緒的實作方法

以上是java學習:什麼是執行緒?最詳細的解釋的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn