3

私はデッドロックのためにオラクルのドキュメントを調べています..私はこのコードを見つけました

public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s"
                + "  has bowed to me!%n", 
                this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
}

よくわかりませんが、どのような場合にデッドロックが発生しますか?

このコードを実行すると、正常に動作します。では、デッドロックが発生する特別なイベントがあるに違いありません。

bow がalphonse最初にオブジェクトで呼び出されたとします。bower オブジェクトで呼び出されalphonseたときに、ロックはオブジェクトに残りますか? bower.bowBack(this)ロックを保持している場合、bow別のオブジェクトの関数はロックを解除するまでロックを取得せずalphonse、デッドロック状態になることはありません..

4

5 に答える 5

4

最初の行を出力した後、bowBack を呼び出す前に Thread.sleep(1000) を配置すると、デッドロックが発生するはずです。とにかく、このデッドロックは発生する可能性がありますが、まれです。

2 つのスレッドがあり、取得される 2 つのロックは異なる順序です。これにより、各スレッドが 1 つのロックを保持したままになり、2 番目のロックを取得できなくなる可能性があります。つまりデッドロック。

注: スレッドの開始には多くの時間がかかります。つまり、最初のスレッドが 2 番目のスレッドが開始する前に完了する可能性があるため、問題が発生する可能性はほとんどありません。


これがあなたのためのパズルゲームです。これによりデッドロックが発生します。理由がわかりますか?

class A {
    static final int i;
    static {
        i = 128;

        Thread t = new Thread() {
            public void run() {
                System.out.println("i=" + i);
            }
        };
        t.start();
        try {
           t.join();
        } catch (InterruptedException e) {
           Thread.currentThread().interrupt();
        }
    }
于 2013-06-21T12:29:18.307 に答える
3

マルチスレッドを扱っているため、2 つのスレッドでの操作は相互に任意の順序で発生する可能性があります。したがって、この場合、両方のアクターが実行さbowれ、その後両方が実行を試みると想像してくださいbow_back。とを同期するbowbow_back、両方のオブジェクトがロックされ、いずれのオブジェクトも実行できなくなりbow_backます。両方のオブジェクトは、もう一方が「解放」されるまで待機しますが、これは発生せずbow、「元に戻る」前に戻りません。

于 2013-06-21T12:30:10.717 に答える
1

両方bow()が同時にメソッドに入った場合、または途中でロック解除が発生します。

System.out.println();

「私に頭を下げた!」の両方が表示されない場合。メッセージ、デッドロックが発生しました!

2 番目のスレッドが開始する前に最初のスレッドが終了した場合、デッドロックは発生しません。

コードを Thread.sleep(1000); で拡張します。

public synchronized void bow(Friend bower) {
System.out.println(....);
Thread.sleep(1000);
...
}

次に、両方のスレッドが bow() に入り、デロックが発生します。

于 2013-06-21T12:41:09.107 に答える
0

弓の最後に A と G が bowBack を呼び出し、A から G.bow が呼び出され、G から A.bow が呼び出され、A と G の弓が同期されます。そのため、両者はお互いが終了するのを待ちます。

于 2013-06-21T12:33:39.383 に答える