6

私の理解によると、次のコードはデッドロックになるはずです。その理由は、スレッド t1 が静的オブジェクト firstData をロックするときに、クラスのロックを取得したためです。したがって、別の静的オブジェクト secondData をロックしようとすると、リクエストはブロックされます。

ただし、プログラムは正常に実行され、印刷されます*** Successfully acquired both the locks

ここにない静的オブジェクトのロックについてはどうですか?

public class Deadlock {
    public static void main(String[] args) {

        Thread t1 = new Thread(new DeadlockRunnable());
        t1.start();
    }
} 

 class DeadlockRunnable implements Runnable {
    static  Object firstData = new Object();
    static  Object secondData = new Object();

    public void run() {
        synchronized(firstData) {
            synchronized(secondData) {
                System.out.println("*** Successfully acquired both the locks");
            }
        }
    }

}

ロックはクラスではなくオブジェクトにあると答えたすべての人は、これを見てください

4

2 に答える 2

14

まず、ここで間違いがあります:

その理由は、スレッド t1 が静的オブジェクト firstData をロックするときに、クラスのロックを取得したためです。

静的オブジェクトをロックすると、クラスではなく、そのオブジェクトのみがロックされます。2 つの別々のオブジェクトをロックしています。

あなたが参照した質問は、同期されたステートメントではなく同期されたメソッドに関するものです。これら 2 つの関連する構造は、わずかに異なる方法で機能します。


第 2 に、同じオブジェクトをロックしていても、コードはデッドロック ( ideone ) しません。組み込みロックは再入可能です。これは、スレッドが同じロックを 2 回取得しようとしても、スレッド自体がデッドロックしないことを意味します。

再入可能同期

スレッドは、別のスレッドが所有するロックを取得できないことを思い出してください。ただし、スレッドは既に所有しているロックを取得できます。スレッドが同じロックを複数回取得できるようにすると、再入可能な同期が可能になります。これは、同期されたコードが直接的または間接的に、同期されたコードも含むメソッドを呼び出し、コードの両方のセットが同じロックを使用する状況を表しています。再入可能な同期がなければ、同期されたコードは、スレッド自体がブロックされるのを避けるために、さらに多くの予防策を講じる必要があります。

ソース

于 2012-04-19T22:30:35.530 に答える
1

「スレッド t1 が静的オブジェクト firstData をロックするとき、彼はクラスのロックを取得しました」
なぜそう思うのかわかりません。t1 は、含まれるクラスではなく、firstData のロックを取得します。そのままのコードでデッドロックが発生する可能性はありません。

編集
あなたのコメントに続いて、リンクはこれら2つの宣言の違いについてです:

public synchronized method() // lock on the instance (this)
public static synchronized method() // lock on the class (Myclass.class)

しかし、デッドロックとのリンクはありません。

于 2012-04-19T22:31:22.877 に答える