2

このJavaプログラムをコンパイルして実行しましたが、出力が不快です。スレッドがデッドロック状態にある理由がわかりません。誰かが私がプログラムの出力を理解するのを手伝ってくれますか?

class A {
synchronized void foo(B b) {
    String name=Thread.currentThread().getName();
    System.out.println(name+"entered A.foo");

    try {
        Thread.sleep(1000);
    } catch(Exception e) {}
    System.out.println(name+"trying to call B.last()");
    b.last();
}
synchronized void last() {
    System.out.println("inside A.last");
}
}

class B {
synchronized void bar(A a) {
    String name=Thread.currentThread().getName();
    System.out.println(name+"entered B.bar");
    try {
        Thread.sleep(1000);
    } catch(Exception e) {
        System.out.println("b interrupted");
    }
    System.out.println(name+"trying to call A.last()");
    a.last();
}
synchronized void last() {
    System.out.println("inside A.last");
}
}

class DeadLock implements Runnable {
A a=new A();
B b=new B();
DeadLock() {
    Thread.currentThread().setName("mainthread");
    Thread t=new Thread(this,"racingthread");
    t.start();
    a.foo(b);
    System.out.println("back in main thread");
}
public void run() {
    b.bar(a);
    System.out.println("back in other theread");
}
public static void main(String...d) {
    new DeadLock();
}
}

私のコンピューターの出力は

mainthreadentered A.foo

racingthreadentered B.bar

mainthreadtrying to call B.last()

racingthreadtrying to call A.last()
4

4 に答える 4

5

古典的なデッドロックがあります。

  • A.foo()ロックとロックを試みるa呼び出しb.last()b
  • B.bar()ロックとロックを試みるb1呼び出しa.last()a

それぞれが他方のロックを必要とするため、どちらも続行できません。

スレッドがデッドロック状態にある理由がわかりません。

それがあなたのプログラムが行うように設計されているからです。


ロックが不要な場合、最も簡単な解決策はすべてのsynchronizedキーワードを削除することです。

于 2012-08-28T17:23:26.577 に答える
0

オブジェクトbはオンbar()aオンfoo()でロックされているため、呼び出すとlast()、各関数は他の関数がロックを解除するのを待っています。それがデッドロックを引き起こしています

于 2012-08-28T17:20:31.150 に答える
0

宿題のように見えます。しかし、答えは、deadlock()のコンストラクター内に別のスレッドをセットアップするという事実にあると思います。

タイマーを使用してスレッドを整列させるため、両方のスレッドが競合し、同期されたメソッドの1つでロックされる可能性があります。それを実行せずに私の推測です。

また、クラス名は大文字にする必要があります。

于 2012-08-28T17:20:51.930 に答える
0

デッドロックの解決策はありません。プログラマーは、デッドロックが発生しないように注意してコーディングする必要があります。

于 2012-08-28T19:37:30.690 に答える