探討Java中的多執行緒概念 - foojay
解釋Java程式語言中多執行緒的複雜性,讓我們從快速概覽和理解核心概念開始。
作業系統中的執行緒概念
- 執行緒:執行緒是輕量級程式,但它在多個方面與程式不同。執行緒的主要特徵是它建立併發執行過程的感覺。它可以有效地分配工作並執行單個任務,可以用於排程和非同步執行任務,它具有比程式更有效的上下文切換機制,並且它與其他執行緒共享記憶體空間,但是可以擁有自己的儲存空間
- 關鍵部分Critical Section:程式碼的關鍵部分被標識為焦點區域,多個執行緒可以同時訪問該焦點區域並可以修改狀態。由於共享資源時會同時進行修改,因此需要對訪問進行控制。
- 訊號量:訊號量是一種資源計數,可用於控制對共享資源的訪問,尤其是在多執行緒環境中。
- 互斥量:互斥量是一種同步結構,僅允許一個執行緒一次使用資源並擁有與之相關的所有權。
- 監控器:一種同步構造,它允許相互排斥並具有等待條件為真的能力。
- 死鎖:在訪問程式碼的關鍵部分時,可能存在多個執行緒訪問多個共享資源的情況。在這種情況下,當單個執行緒需要訪問共享資源時,它可能首先需要釋放當前持有的共享資源。關於同一資源的另一個同時執行的執行緒也可能是正確的。當無法實現這種互斥時,將導致死鎖。
- 死鎖預防:防止死鎖情況發生的技術構成了死鎖預防。
- 死鎖處理:死鎖的檢測及其消除構成了死鎖處理。
- 重入:在不完成其先前呼叫的情況下可以重新輸入方法或子例程的情況。
Java中執行緒介面或類
- 執行緒:解釋了執行緒類的重要方法,並在程式碼示例中顯示了用法。即使是有經驗的Java程式設計師在多執行緒中,最令人困惑和常見的錯誤是理解鎖。在每種方法中,我都提供了共享物件上的鎖定狀態。
- Runnable:建立執行緒的另一種方法是實現此介面。可以通過實現Runnable介面或擴充套件Thread類來在Java中建立執行緒。程式設計師將必須重寫此介面中的run()方法以實現邏輯。
- start(),會獲取鎖定狀態;這是用來排程執行緒執行的方法。一旦計劃好並且CPU週期可用,該執行緒就會實際執行。
- run(),會獲取鎖定;Thread執行時會隱式呼叫它以開始執行執行緒。
- yield(),鎖定保持;此方法將控制權產生或轉移給具有相同優先順序的另一個執行緒。它不能保證將控制權轉移到哪個執行緒,也不能保證。下面的程式碼片段還顯示瞭如何通過擴充套件Thread類來建立Thread。
- sleep(),鎖定會保持;此方法使當前正在執行的執行緒在給定的時間段內暫停執行。時間段以毫秒為單位指定。它丟擲一箇中斷的異常,該異常需要由程式設計師處理。
- join(),鎖定會保持;這導致執行模式,其中所有執行緒都在當前執行緒的末尾加入。換句話說,當前執行緒在切換到另一個執行緒之前已完成。它將引發一箇中斷的異常,程式設計師必須處理該異常。
- suspend(),已棄用。
- resume(),已棄用;不建議使用這些執行緒方法,因為它可能導致死鎖和凍結程式。當必須恢復掛起執行緒的執行緒需要在呼叫resume()之前訪問該掛起執行緒持有的共享資源或鎖時,尤其如此。
- stop(),已棄用;不建議使用此執行緒方法,因為由於損壞的物件而產生的狀態不一致。我不提供程式碼示例,因為它是非常直接的用法–但即使使用非常舊的編譯器版本,我也不建議使用這些方法。
Java中的物件
Java中的Object類固有地包含可以控制對此物件的訪問的方法,尤其是在共享或多執行緒應用程式中。
- wait(),當前物件鎖定已釋放,已持有其他鎖定;wait()方法使當前執行緒暫停執行並進入等待狀態。它還釋放它在當前物件上持有的鎖,但保留其他物件上的所有其他鎖。
- notify(),任意等待執行緒處於鎖定狀態;notify()方法通知正在等待獲取當前共享物件上的鎖的任意執行緒。
- notifyAll(),任意等待的執行緒正在鎖定狀態;此方法的notifyAll()對應物件通知所有正在等待獲取共享庫上的鎖的執行緒。
- 關於鎖的注意事項:每當您想到Java中的鎖或監視器時,都可以使用此原則:執行緒進行的任何併發修改都不應導致物件損壞。唯一的例外是wait()和notify()機制,它們可能導致交換或切換控制之前更改共享資源或物件。損壞的物件是指狀態發生不希望的或可破壞的更改的物件。
- 同步synchronized:在Java中,sync關鍵字用於控制對程式碼關鍵部分的訪問。另外,它是Java中的執行緒監視器的實現。sync關鍵字既可以應用於靜態方法,也可以應用於例項級方法或塊。當執行緒進入同步的塊或方法時,它將獲得對該類或物件的鎖定。對於靜態同步方法,單個鎖儲存在類級別,並且不同於每個類例項儲存的例項級鎖。sync關鍵字在共享資源上提供了必要的互斥。只能在同步塊或方法中呼叫wait(),notify()和notifyAll()。Java不固有地支援互斥物件。
案例研究:設計一個多執行緒系統,該系統的共享資源只能採用兩個值。0或1。它應該有兩種方法,一種用於遞增和遞減的方法,由兩個執行緒同時呼叫。其中一個執行緒只能不斷增加,而另一個只能不斷減少。它們的操作應互斥。
解決方案:它是生產者-消費者問題的簡化版本:
package org.csi_india.programming.workbench.multithreading; public class CSIDecrementer implements Runnable { CSISharedObject csiSharedObject; CSIDecrementer(CSISharedObject csiSharedObject) { this.csiSharedObject=csiSharedObject; } public void run() { while(true) csiSharedObject.decrementerAccess(); } } package org.csi_india.programming.workbench.multithreading; public class CSIIncrementer implements Runnable { CSISharedObject csiSharedObject; CSIIncrementer(CSISharedObject csiSharedObject) { this.csiSharedObject=csiSharedObject; } public void run() { while(true) csiSharedObject.incrementerAccess(); } } package org.csi_india.programming.workbench.multithreading; public class CSIWorkbench extends Thread { public static void main(String args) { CSISharedObject csiShared=new CSISharedObject(); Thread csiThread01=new Thread(new CSIIncrementer(csiShared)); csiThread01.start(); Thread csiThread02=new Thread(new CSIDecrementer(csiShared)); csiThread02.start(); } } package org.csi_india.programming.workbench.multithreading; public class CSISharedObject { // access from within this class only private int; public synchronized void decrementerAccess() { try { if (x = ) { x--; notify(); } else { wait(); } } catch (InterruptedException e) { System.out.println("thread interrupted"); } } public synchronized void incrementerAccess() { try { if (x = ) { x++; notify(); } else { wait(); } } catch (InterruptedException e) { System.out.println("thread interrupted"); } } |
以下是為Java中的非同步任務執行提供了更細化或受控的訪問。
- Callable:類似於Runnable的另一個類,其例項可能由另一個執行緒執行。
- Executors:用於建立執行緒池的幫助程式介面。
- ExecutorService:非同步任務執行器,可用於提交Runnable或Callable任務以執行,然後通過Future物件跟蹤它們的狀態。
- Future:物件從任務提交返回到非同步任務執行器,可使用該執行器監視任務狀態。
- AtomicInteger: Java中的一種Integer物件,它使用硬體指令執行併發的無鎖更新。
- Condition:條件將物件監視方法(wait,notify和notifyAll()分解為不同的物件,從而通過將它們與任意Lock實現結合使用,從而使每個物件具有多個等待集。對於同步的方法和語句,Condition代替了Object監視器方法的使用,Condition是Java介面。
- signal():喚醒一個等待的執行緒。
- signalAll():喚醒所有等待的執行緒。
- await():使當前執行緒等待,直到被訊號通知或中斷為止。鎖定:與使用同步方法和語句相比,鎖定實現提供了更廣泛的鎖定操作。鎖是一個介面。
- ReentrantLock:可重入互斥鎖,其基本行為與隱式監視器鎖相同。它是Lock的具體實現。
相關文章
- 【java】【多執行緒】程式、執行緒的基本概念(1)Java執行緒
- Java中的多執行緒Java執行緒
- Java中多執行緒的案例Java執行緒
- Java 多執行緒基礎(一)基本概念Java執行緒
- Java高併發與多執行緒(一)-----概念Java執行緒
- 多執行緒基本概念執行緒
- Java中的多執行緒詳解Java執行緒
- Java多執行緒-執行緒中止Java執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒
- Java多執行緒-執行緒池的使用Java執行緒
- 【Java多執行緒】輕鬆搞定Java多執行緒(二)Java執行緒
- Java 多執行緒設計模式之基礎概念Java執行緒設計模式
- java多執行緒核心api以及相關概念(一)Java執行緒API
- Java多執行緒中執行緒安全與鎖問題Java執行緒
- java——多執行緒Java執行緒
- java多執行緒Java執行緒
- Java - 多執行緒Java執行緒
- java 多執行緒Java執行緒
- java多執行緒之執行緒的基本使用Java執行緒
- 【Java】【多執行緒】執行緒的生命週期Java執行緒
- Java多執行緒之執行緒中止Java執行緒
- Java多執行緒-執行緒狀態Java執行緒
- Java多執行緒-執行緒通訊Java執行緒
- java 多執行緒守護執行緒Java執行緒
- Java多執行緒(2)執行緒鎖Java執行緒
- java多執行緒9:執行緒池Java執行緒
- 【java多執行緒】(二)執行緒停止Java執行緒
- “多執行緒”重點概念整理執行緒
- Java多執行緒學習(一)Java多執行緒入門Java執行緒
- Java多執行緒(一)多執行緒入門篇Java執行緒
- 探討阻塞佇列和執行緒池原始碼佇列執行緒原始碼
- java多執行緒中的synchronized的byte[0]Java執行緒synchronized
- 對多執行緒程式,單核cpu與多核cpu如何工作相關的探討執行緒單核
- java多執行緒5:執行緒間的通訊Java執行緒
- 【Java】【多執行緒】執行緒池簡述Java執行緒
- iOS多執行緒詳解:概念篇iOS執行緒
- java 多執行緒CountDownLatchJava執行緒CountDownLatch
- java 多執行緒-3Java執行緒