簡體   English   中英

是否按方法或按類發生死鎖?

[英]Does deadlock happen per method or per class?

想象一下,我擁有帶有多個同步方法的Class First 當線程鎖定類First ,它是按方法還是按類鎖定? 例如,以下代碼是否發生死鎖?

public class DeadLockQuestion {

    public static class First{
        public synchronized void a(){

        }
        public synchronized void b(){

        }
        public synchronized void c(){

        }   
        public synchronized void d(){

        }
        public synchronized void e(){

        }       
    }

    public static void main(String... args){
        First f = new First();

        //This code is run in Thread 1
        f.a();
        // End
        //This code is run in Thread 2 simultanously
        f.b();
        //End
        // We have also Threads 3 & 4 & 5 that invoke c,d and e simultanously

    }

}

您在Java中有兩個鎖。 一種是對象鎖定。 另一個是Class Lock。 對象鎖僅鎖定對同步非靜態功能的訪問。 和類鎖僅鎖定同步的靜態函數。 對您來說,它是對象f上的對象鎖。 因此,所有同步的非靜態功能都被鎖定為對象f 由於所有線程都使用相同的對象f ,因此只有一個線程一次能夠訪問您的非靜態函數a(), b(),... 在這里閱讀更多

does deadlock happen for the following code?

不,您的情況不會發生。 因為當一個Thread持有該鎖時,其他線程無法進入您的同步函數中。 DeadLock happens due to resources.
您只有一個資源,那就是Object f 這里沒有死鎖的意義,因為類First不會鎖定另一個對象, 並且不會發生循環鎖定。 死鎖需要循環鎖定

一些信息:

  1. Java中的同步保證了沒有兩個線程可以執行同步方法,該方法需要同時或並發執行相同的鎖定。
  2. 同步關鍵字只能與方法和代碼塊一起使用。 這些方法或塊可以是靜態的也可以是非靜態的。
  3. 每當線程進入java同步方法或塊時,它都會獲得一個鎖,而每當線程離開java同步方法或塊時,它將釋放該鎖。 即使線程在完成后或由於任何錯誤或異常而離開同步方法時,也會釋放鎖定。
  4. 靜態同步方法和非靜態同步方法都可能同時或同時運行,因為它們鎖定在不同的對象上。
    有用的資料在這里這里

死鎖發生在線程上,而不是方法或類上。

死鎖線程也持有鎖,但是在這種情況下,由於您沒有演示實際的死鎖情況,因此無法分辨出哪些鎖(如果兩個線程調用f同步方法,而另一個等待,則等待;死鎖至少需要兩個鎖)。

要獨立鎖定每個方法,請在每個方法中使用一個同步塊,然后鎖定另一個對象。

如果您在類中已經有一個適當的對象(並且應該是最終對象,以防止潛在的問題),則可以使用該對象。 如果沒有創建一個private final Object aLock = new Object(); 然后鎖定它,例如:

private final Object aLock = new Object();

public void a() {
    synchronized(aLock) {
         // Do stuff that needs the lock
    }
    // do stuff that doesn't need the lock
}

始終將鎖保持所需的時間,但不再需要。

a()是同步方法時, fa()字面意思是:

synchronized(f){
    f.a();
}

因此,在這種情況下,對象監視器f會發生鎖定。 在您的情況下,您將需要第二個對象來創建死鎖,我認為用單個對象監視器創建死鎖是不可能的。 典型的死鎖模式是不維護鎖獲取順序時,即在兩個不同的線程中發生時:

synchronized(a){
     synchronized(b){
         ...
     }
}
// and
synchronized(b){
     synchronized(a){
         ...
     }
}

首先, 死鎖與線程而不是類或方法一起發生。

當存在周期性的鎖依賴性時,就會發生死鎖。

Thread A ---> locks L1        ---> tries to lock L2

     Thread B ----> locks L2                         ------> tries to lock L1

圖片來源:FusionReactor死鎖插件

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM