4

次のコードが、オブジェクトロックの定義に違反しているように見える出力をどのように生成するかわかりません。確かに、「取得したロック」メッセージの印刷を許可するスレッドは1つだけですが、両方とも印刷できますか?

class InterruptThreadGroup {
    public static void main(String[] args) {
        Object lock = new Object();
        MyThread mt1 = new MyThread(lock);
        MyThread mt2 = new MyThread(lock);
        mt1.setName("A");
        mt1.start();
        mt2.setName("B");
        mt2.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        // Thread.currentThread().getThreadGroup().interrupt();
    }
}

class MyThread extends Thread {
    private Object lock;

    public MyThread(Object l) {
        this.lock = l;

    }

    public void run() {
        synchronized (lock) {
            System.out.println(getName() + " acquired lock");
            try {
                lock.wait();
            } catch (InterruptedException e) {
                System.out.println(getName() + " interrupted.");
            }
            System.out.println(getName() + " terminating.");
        }
    }
}
4

2 に答える 2

7

これは、の呼び出しがlock.wait()ロックを解放し、2番目のスレッドが同期ブロックに入ることができるようにするためです。javadocから抽出

スレッドはこのモニターの所有権を解放し、notifyメソッドまたはnotifyAllメソッドのいずれかを呼び出して、このオブジェクトのモニターで待機しているスレッドにウェイクアップするように別のスレッドが通知するまで待機します。次に、スレッドはモニターの所有権を再取得できるようになるまで待機し、実行を再開します。

コードには次のようないくつかの問題があることに注意してください。

  • whileループの外で待つべきではありません
  • どこにも通知がないので、あなたの待機は永遠に続く可能性があります
  • Threadを直接拡張するよりも、タスクにRunnableを実装させ、それを引数としてThreadのコンストラクターに渡すことをお勧めします。
于 2013-01-23T17:01:23.573 に答える
0

同期ブロックを使用するか、呼び出しを待機する必要があります。それらを一緒に使用しても機能しません。待機呼び出しを使用する場合、ロックは同期ブロック内のオブジェクトによって解放されます。

したがって、行を削除するlock.waitと、プログラムは希望どおりに機能します。同期ブロックはすべてのロックを自動的に処理します。

待機を使用している場合は、通知を使用する必要があります。

これについての良いスレッドは次のとおりです。wait()が常に同期ブロックにある必要があるのはなぜですか

于 2013-01-23T17:07:05.917 に答える