Java 併發中 Lock 和 Monitor 的區別
在 Java 中,併發是一種允許在單個處理器或多個處理器上同時執行多個任務或程序的技術。它可以提高應用程式的效能和響應能力。但是,它也為 Java 開發人員帶來了新的挑戰和複雜性,例如同步和死鎖。為了處理這些複雜性,Java 提供了鎖和監視器。兩者相互關聯,用於同步對共享資源的訪問並確保執行緒安全。但是,在功能和用法方面,鎖和監視器之間存在一些差異。
Lock 與 Monitor
監視器 (Monitor)
當我們在多執行緒環境中工作時,多個執行緒訪問共享資源,我們需要某種方法來確保一次只有一個執行緒訪問資源。因為如果我們未能建立這些執行緒之間的合作,可能會導致分配任務的錯誤結果。同步是實現此目的的方法。
同步的核心是監視器,它是一個建立互斥鎖的物件。監視器就像一個同步區域,在特定時間只能被一個執行緒獲取。
鎖 (Lock)
當多個執行緒嘗試訪問共享資源時,Lock 物件透過“lock()”和“unlock()”方法限制一次只有一個執行緒訪問。執行緒透過“tryLock()”方法請求獲取 Lock 物件。當鎖分配給它時,並在任務完成後釋放鎖。在資源繁忙期間,其他執行緒在佇列中等待輪到它們。
鎖允許執行緒獨立地處理共享資源,而不會受到其他執行緒的干擾。此外,單個執行緒可以多次請求鎖。
方法
建立一個名為“Thrd”的類,並在其中定義一個名為“operation()”的靜態同步方法以及一個引數。
現在,在這個方法中,使用一個將執行 4 次的 for 迴圈執行求和運算。此迴圈的 try 塊將以指定的時間間隔(即 1000 毫秒)列印輸出。
接下來,建立三個執行緒。在這些執行緒中,將引數傳遞給“operation()”方法。
最後,在主方法中為執行緒類建立三個物件,並使用內建方法“start()”執行它們。
同步示例
以下示例演示了我們到目前為止討論的內容。
class Thrd { public static synchronized void operation(int data) { for(int i = 1; i <= 4; i++) { int sum = i + data; System.out.println(sum); try { // each iteration performed with interval of 1 sec Thread.sleep(1000); } catch(Exception exp){} } } } class Thrd1 extends Thread { // thread number 1 public void run() { Thrd.operation(1); } } class Thrd2 extends Thread { // thread number 2 public void run() { Thrd.operation(5); } } class Thrd3 extends Thread { // thread number 3 public void run() { Thrd.operation(10); } } public class ThrdExecution { public static void main(String args[]) { // creating object for thread class Thrd1 oprt1 = new Thrd1(); Thrd2 oprt2 = new Thrd2(); Thrd3 oprt3 = new Thrd3(); // Starting the thread operation oprt1.start(); oprt2.start(); oprt3.start(); } }
輸出
2 3 4 5 11 12 13 14 6 7 8 9
Lock 和 Monitor 的區別
鎖 (Lock) |
監視器 (Monitor) |
---|---|
它提供了對同步的顯式控制,這意味著它允許程式設計師顯式地獲取和釋放它們。 |
它提供了對同步的隱式控制。它由執行時環境自動管理。 |
它比監視器使用得相對較少。 |
它被廣泛使用 |
它實現起來有點複雜,但比監視器更靈活。 |
它實現起來更簡單,與鎖相比,靈活性較差。 |
鎖可以被執行緒多次獲取和釋放。 |
執行緒每個資源只能使用一個監視器。 |
鎖允許執行緒透過呼叫其 tryLock() 方法來檢查它是否可以獲取鎖。 |
監視器無法做到這一點。 |
結論
在本文中,我們討論了同步中一個非常重要的主題,它促使執行緒按順序執行程式碼塊。Lock 和 Monitor 是同步的基礎。從邏輯上講,它們之間沒有區別,它們實際上是互補的。當執行緒獲取鎖時,它會進入監視器,監視器是一個同步區域。