6

プロジェクトに取り組んでいるときに、本番システム向けの次のコードに出くわしました。

public static void sleepUntil(long millisecondToWake) {
    while (true) {
        long currentMillisecond = System.currentTimeMillis();
        if (currentMillisecond >= millisecondToWake) {
            break;
        }
        try {
            Thread.sleep(millisecondToWake - currentMillisecond);
        }
        catch (InterruptedException ignoredException) {
            // do nothing
        }
    }
}

私は常に、Joshua Bloch が『Effective Java』で公開したように、例外をドロップしないという基本原則に固執してきました。また、他の誰かが例外をドロップした場所でコードをデバッグしなければならなかった私自身の広範な経験をサポートしてきました。今日まで、それが良いアイデアであるケースを見つけていません (チェックされた例外をキャッチしてランタイムをスローすることは、議論の余地があるほど合理的ですが、ここではそれらのケースについては話していません)。

コメントをお寄せいただきありがとうございます。

4

2 に答える 2

5

この特定の例外に関する素晴らしい記事を次に示します。

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html

ただし、基本的には無視すべきではありません。少なくともコードが行うべきことは、割り込みを伝播することです。

catch (InterruptedException e) { 
    // Restore the interrupted status
    Thread.currentThread().interrupt();
}

作成者は、スレッドのスリープが中断されても気にしません (これは、例外を飲み込む正当な理由です)。ただし、作者がコードを書いたときに知らなかった、または考えていなかった、スレッド内の別の場所で中断が必要になる場合があります。

割り込み要求に対処する予定があるかどうかに関係なく、現在のスレッドを再割り込みする必要があります。これは、1 つの割り込み要求に複数の「受信者」が含まれる可能性があるためです。標準のスレッド プール (ThreadPoolExecutor) ワーカー スレッドの実装は中断に応答するため、スレッド プールで実行されているタスクを中断すると、タスクがキャンセルされ、スレッド プールがシャットダウンされていることが実行スレッドに通知される可能性があります。

于 2013-07-24T11:08:56.560 に答える
3

その特定の例では、合理的なアプローチとは思えません。特に、ユーザーがプログラムを終了したい場合 (たとえば)、JVM はスリープ状態のメソッドが終了するまでハングしますが、これは不合理に思えます。

IMO、安全に無視できる唯一の状況は次のInterruptedExceptionとおりです。

  • メソッドを実行するスレッドを完全に制御できます。
  • 例外が無視された直後に終了します。

その他の状況では、次のことを行う必要があります。中断フラグをリセットして、すぐに終了します。

たとえば、これは問題ありません。

//the task is local, nobody else can access it
final Runnable localRunnable = new Runnable() {
    public void run() {
        //catch, ignore and exit immediately
        try { Thread.sleep(10000); } catch (InterruptedException e) {}
    }
}
//it is your own thread and you have full control over it
new Thread(localRunnable).start();
于 2013-07-24T11:09:19.790 に答える