最初のケースでは、ループ内で Thread.sleep を使用すると、Netbeans IDE がループ内で Thread.sleep を使用しないようにという警告を発行します。何故ですか?
Netbeans は、ループ状態をテストしないと考えており、コードが不必要に一時停止するためだと思います。
2 番目のケースでは、無限の空の while ループを使用すると、パフォーマンスのオーバーヘッドになりますか?
そうそう。スレッドのスピンは CPU を消費し、パフォーマンス シンクになります。
ユーザーの選択に応じて、スレッドによって実行されているアクションを一時停止するには、どの方法(上記またはそれ以外)を選択する必要がありますか?
ない?スレッドを一時停止する必要があるかどうかをテストするために使用し、volatile boolean pauseFlag
待機/通知と組み合わせて一時停止を解除します。またはAtomicBoolean
、 a をラップするvolatile boolean
が、同期できるオブジェクトでもある an を使用できます。たぶん次のようなもの:
// using `AtomicBoolean` which wraps a `volatile boolean` but is const object
// NOTE: we _can't_ synchronized on Boolean, needs to be constant object reference
private final AtomicBoolean pauseFlag = new AtomicBoolean(false);
...
while (!Thread.currentThread().isInterrupted()) {
if (pauseFlag.get()) {
synchronized (pauseFlag) {
// we are in a while loop here to protect against spurious interrupts
while (pauseFlag.get())) {
try {
pauseFlag.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
// we should probably quit if we are interrupted?
return;
}
}
}
}
...
}
...
public void pause() {
pauseFlag.set(true);
}
...
public void resume() {
pauseFlag.set(false);
synchronized (pauseFlag) {
pauseFlag.notify();
}
}
sleep(...)
2つのうちの1つを選ばなければならないとしたら、ループを選ぶと思います。偶数sleep(1)
はスピンよりもはるかに優れています。~1ms よりも早く一時停止を解除する必要がありますか? ただし、待機/通知が最も効率的です。
同期とは関係ないので、wait/notify は使いたくない。
@Jon が述べたように、2 つのスレッド間で通信しようとしているため、ここでは何らかの同期が必要です。確かに、メモリの同期が必要です。そうしないと、への更新pauseFlag
がスレッド間で共有されることが保証されません。これは、volatile
プリミティブ onによって処理されpauseFlag
ます。wait/notify (これには が必要synchronized
です) を使用することで、コードはウェイクアップに関してはるかに効率的になります。