6

私が理解しているように、これは Java のマルチスレッドの非常に一般的なスニペットです。

boolean loaded = false;
Object lock = new Object();

public void block() {
    synchronized (lock) {
        while(!loaded)
            lock.wait(); // Unhandled exception type InterruptedException
    }
}

そして別のスレッドで

public void done () {
    synchronized (lock) {
        loaded = true;
        lock.notify();
    }
}

しかし、try と catch をどこに配置すればよいかわかりません。同期ブロック全体を囲むことができlock.wait()ますか? 経験則とは何ですか?それは本当に重要ですか?

ハンドリングについては、この場合コールThread.currentThread().interrupt()してもよろしいですか?

4

2 に答える 2

6

Brian Goetz による記事を検討することをお勧めします: Java の理論と実践: 割り込み例外の処理

一般に、何をすべきかわからない場合は、何もせずに、ロックの待機中にこのメソッドが中断される可能性があることを呼び出し元コードに知らせます。これを行うには、 throws InterruptedExceptionをメソッド シグネチャに追加します。

何らかの理由で try/catch ブロックを追加して例外を処理する必要がある場合は、Thread.currentThread().interrupt()で実行できますが、再スローするのが適切な場合があります。

于 2013-01-09T12:09:27.977 に答える
3

しかし、try と catch をどこに配置すればよいかわかりません。同期ブロック全体を囲むか、lock.wait() のみを囲むことができますか? 経験則とは何ですか?それは本当に重要ですか?

lock.wait()blockメソッドで例外をスローできる唯一の行です。したがって、待機中に try/catch を配置するか、メソッド本体全体を含めるかは、実行の観点からは違いはありません (もちろん、両方の場合でループを終了すると仮定します-ループを続行したい場合は、try/catch ブロック明らかにループ内にある必要があります)。

言い換えれば、これは単にスタイルの問題です。この他の議論を参照してください。私は個人的にこれがより読みやすいと思います:

try {
    synchronized (lock) {
        while (!loaded) {
            lock.wait(); // Unhandled exception type InterruptedException
        }
    }
} catch (InterruptedException e) {
    //to ignore me or not to ignore me, that is the question
    Thread.currentThread().interrupt();
}

処理のために、この状況で Thread.currentThread().interrupt() を呼び出しても問題ありませんか?

以下の最初の例では、InterruptedException をキャッチして、スレッドを再中断せずにループを終了しても問題ありません。いずれの場合も run メソッドが終了し、スレッドが停止するためです。

new Thread(new Runnable() {

    @Override
    public void run() {
        block();
    }
}).start();

以下の 2 番目の例では、スレッドを再中断して、終了した理由block()がロードされたことが true になったのか、それとも中断されたのかを run メソッドに知らせる必要があります。

public void run() {
    while(!Thread.currentThread().isInterrupted()) {
        loaded = false;
        System.out.println("Launching data load");
        block(); //if false has become true, loop, if interrupted, exit
    }
}

メソッドがどのように使用されるかわからない場合は、スレッドを再度中断することをお勧めします。

于 2013-01-09T12:54:05.220 に答える