Java 多線程的一些概念

《深入理解 Java 虛擬機》 第五部分

1. Java 線程內存模型

線程、主內存、工作內存三者的交互關系

變量:討論線程的時候,變量是指實例字段、靜態字段和構成數組對象的元素,但不包括局部變量和方法參數,因為后者是線程私有的,不會被共享,自然也不存在競爭關系。

Java內存模型規定了所有的變量都存儲在主內存中。每個線程還有自己的工作內存,線程的工作內存中保存了被該線程中使用到的變量的主內存拷貝副本(對于具體對象,虛擬機可能不會拷貝整個對象,而是只拷貝線程訪問到的字段),線程對變量的所有操作都必須在工作內存中進行,而不能直接讀寫主內存中的變量。不同的線程之間也無法直接訪問對方工作內存中的變量,線程間變量值的傳遞均需要通過主內存來完成。(volatile 變量依然有工作內存拷貝,只是讀寫時有特殊的操作順序性規定)

2. 原子性、可見性與有序性

原子性:即一個操作或者多個操作 要么全部執行并且執行的過程不會被任何因素打斷,要么就都不執行。
我的理解就是,當一個線程中的一段代碼要操作(讀/寫)一些變量的值得時候,代碼運行的結果不會被其他線程影響
很多人會說int b = a不是原子操作,就是因為其他線程可能同時修改了 a 的值,影響了最終 b 的結果。其實這暗含了對b來說,a不是局部變量。如果a、b是同一對{}中間的局部變量,其他線程應該也是看不到a的,并不會修改a的值。只有a是一個實例的成員變量,或者靜態成員變量的時候,才會多線程可見。
synchronized 塊之間的操作也具備原子性

可見性:當一個線程修改了共享變量的值,其他線程能夠立即得知這個修改。
所以這個“可見”,應該是指“可以看見變量發生了變化”。

有序性:線程內表現為串行的語義;如果在本線程中觀察其他線程,所有操作都是無序的(因為“指令重排序”和“工作內存與主內存同步延遲”)。
這也說明,指令重排序 不會影響線程內的代碼執行的順序邏輯;雖然進行了重排序,但是線程內并不可感知。

3. 先行發生原則

先行發生原則:在Java內存模型中定義了兩項操作順序之間的偏序關系,如果操作A先行發生于操作B,其實就是說在發生操作B之前,操作A產生的影響能被操作B觀察到,“影響”包括修改了內存中共享變量的值,發送了消息,調用了方法等。
Java內存中包括下列一些天生發生的先行發生關系,無須任何同步協助:

  • 程序次序執行規則:在一個線程內,按照代碼順序執行,前面的操作先行發生于書寫在后面的操作。

  • 管程鎖定規則:一個unlock操作先行發生于后面(時間上的先后)對同一個鎖的lock操作。

  • volatile變量規則:對于一個volatile變量的寫操作先行發生于后面對這個變量的讀操作。

  • 線程啟動規則:Thread對象的start()方法先行發生于此線程的每一個動作。

  • 線程終止規則:線程的所有操作都先行發生于對此線程的終止操作

  • 線程中斷規則:對線程interrupt()方法的調用先行發生于被中斷線程的代碼檢測到中斷時間的發生。

  • 對象終結規則:一個對象的初始化完成先行發生于它的finalize()方法的開始。

  • 傳遞性:若A先行于B發生,B先行于C,那么得出A先行于C

(線程間的)時間先后順序與先行發生原則之間基本沒有太大的關系(因為存在“指令重排序”和“工作內存與主內存同步延遲”)。
我們衡量并發安全問題的時候不要受到時間順序地干擾,必須以先行發生原則為準。

4. Java 線程的實現

輕量級進程與內核線程之間1:1的關系

對于 Sun JDK 來說,它的 Windows 版與 Linux 版都是使用一對一的線程模型實現的,一條 Java 線程就映射到一條輕量級線程之中,因為 Windows 與 Linux 系統提供的線程模型都是使用一對一的。
而 Solaris JDK可以采用N對M模型。

4. Java 線程的調度

線程調度是指系統為線程分配處理器使用權的過程,主要的調度方式有兩種:

  • 協同式線程調度(Cooperative Threads-Scheduling)
    這種方式是原始方式,由一個線程執行完通知另一個線程。已經很少使用,很容易造成阻塞。

  • 搶占式線程調度(Preemptive Threads-Scheduling)
    主流方式,由系統來根據一系列復雜的規則為每個線程分配執行時間,線程的切換不是由線程自己做主(Java可以有Thread.yield()來讓出執行時間,但是沒有獲取執行時間的方式)。不會有一個線程導致整個進程阻塞的問題。

Java 使用的線程調度方式就是搶占式調度。(后續版本可能會提供協程 Coroutimes 方式來進行多任務處理)

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容