Java 並發庫

開放

Java 中的多線程

Java 虛擬機支持並行計算。所有計算都可以在一個或多個線程的上下文中執行。我們可以輕鬆地為多個線程設置對同一資源或對象的訪問,以及設置一個線程來執行單個代碼塊。

對於分配有多個線程的資源,任何開發人員都需要在讀取和寫入操作期間與線程同步工作。

重要的是,在訪問資源時,您擁有最新的數據,以便另一個線程可以更改它並獲得最新的信息。即使我們以銀行賬戶為例,在錢到賬之前,您也無法使用它,因此始終擁有最新數據很重要。Java 具有用於同步和管理線程的特殊類。

線程對象

這一切都從主(main)線程開始,也就是說,至少你的程序已經有一個正在運行的線程。主線程可以使用CallableRunnable創建其他線程。創建僅在返回結果上有所不同,Runnable不返回結果並且不能拋出已檢查的異常。因此,您獲得了一個利用文件構建高效工作的好機會,但這是非常危險的,您需要小心。

也可以在單獨的 CPU 核心上安排線程執行。系統可以輕鬆地在線程之間移動並通過正確的設置執行特定的線程:即讀取數據的線程首先執行,一旦我們有數據,然後我們將其傳遞給負責驗證的線程,之後我們將它傳遞給線程以執行一些業務邏輯,然後一個新線程將它們寫回。在這種情況下,4 個線程輪流處理數據,一切都會比一個線程更快。每個這樣的流都被轉換為本機 OS 流,但如何轉換取決於 JVM 實現。

Thread類用於創建和使用線程。它有標準的控制機制,也有抽象的機制,例如java.util.concurrent中的類和集合。

Java中的線程同步

通過共享對對象的訪問來提供通信。這樣很有效,但同時工作時也很容易出錯。錯誤有兩種情況:線程干擾 - 當另一個線程干擾您的線程時,以及內存一致性錯誤 - 內存一致性。為了解決和防止這些錯誤,我們有不同的同步方法。

Java 中的線程同步由監視器處理,這是一種高級機制,一次只允許一個線程執行受同一監視器保護的代碼塊。監視器的行為是根據鎖來考慮的;一台顯示器 - 一把鎖。

同步有幾個要點需要注意。第一點是互斥——只有一個線程可以擁有監視器,因此監視器上的同步意味著一旦一個線程進入監視器保護的同步塊,其他線程就不能進入監視器保護的塊。這個監視器直到第一個線程退出同步塊。即多個線程不能同時訪問同一個同步塊。

但同步不僅僅是互斥。同步確保在同步塊之前或同步塊內寫入內存的數據對同一監視器上同步的其他線程可見。退出塊後,我們釋放監視器,另一個線程可以抓住它並開始執行這段代碼。

當一個新線程捕獲監視器時,我們可以訪問並執行該代碼塊,並且在那個時間點將從主內存加載變量。然後我們可以看到之前版本的監視器顯示的所有條目。

如果字段被聲明為volatile或由在任何讀寫之前獲取的唯一鎖保護,則對該字段的讀寫是原子操作。但是如果仍然遇到錯誤,那麼你會得到一個關於重新排序的錯誤(改變順序,重新排序)。它表現為不正確同步的多線程程序,其中一個線程可以觀察到其他線程產生的影響。

線程的互斥和同步的作用,即只有進入隱式獲取鎖的synchronized塊或方法,或者顯式獲取鎖,才能實現它們的正確運行。我們將在下面討論它。這兩種工作方式都會影響您的記憶力,重要的是不要忘記使用volatile變量。

Java 中的可變字段

如果一個變量被標記為volatile,它是全局可用的。這意味著如果一個線程訪問一個volatile變量,它將在使用緩存中的值之前獲取它的值。

寫入工作類似於監視器釋放,讀取工作類似於監視器捕獲。訪問是在“之前執行”類型的關係中執行的。如果你弄明白了,當線程 A 訪問一個volatile變量時,所有對線程 B 可見的就是線程 B 的變量。也就是說,你保證不會丟失來自其他線程的更改。

volatile變量是原子的,也就是說,當讀取這樣的變量時,使用與獲取鎖時相同的效果——內存中的數據被聲明為無效或不正確,然後再次從內存中讀取volatile變量的值。寫入時,使用對內存的影響,釋放鎖時也是如此——一個易失性字段被寫入內存。

Java並發

如果你想製作一個超級高效的多線程應用程序,你必須使用JavaConcurrent庫中的類,它們位於java.util.concurrent包中。

該庫非常龐大且具有不同的功能,因此讓我們看一下里面的內容並將其分為一些模塊:

Java並發

並發集合是一組用於在多線程環境中工作的集合。與阻止訪問整個集合的基本包裝器 Collections.synchronizedList 不同,鎖用於數據段或無等待算法用於並行讀取數據。

隊列- 用於在多線程環境中工作的非阻塞和阻塞隊列。非阻塞隊列專注於速度和操作而不阻塞線程。當您需要“減慢” ProducerConsumer線程時,阻塞隊列適合工作。比如在某些條件不滿足的情況下,隊列為空或者滿,或者沒有空閒的Consumer'a

同步器是用於同步線程的實用工具。它們是“並行”計算的有力武器。

Executors是一個更方便和容易創建線程池的框架,很容易設置異步任務的調度和獲取結果。

鎖相對於基本的synchronized wait notify notifyAll ,是很多靈活的線程同步機制。

原子是可以支持對基元和引用的原子操作的類。

留言
  • 受歡迎
你必須登入才能留言
此頁面尚無留言