在第一种情况下,当我在循环内使用 Thread.sleep 时,Netbeans IDE 发出警告不要在循环内使用 Thread.sleep。这是为什么?
我猜是因为 Netbeans 认为它不会测试循环条件并且代码会不必要地暂停。
在第二种情况下,当我使用无限空while循环时,这是性能开销吗?
嗯,是的。旋转线程将占用 CPU 并成为性能下降器。
根据用户的选择,我应该更喜欢哪种方法(上面提到的或其他方法)暂停线程正在执行的操作?
两者都不?我会使用 avolatile boolean pauseFlag
来测试线程是否应该暂停,并结合等待/通知来取消暂停。或者您可以使用AtomicBoolean
包装 avolatile boolean
但也是我们可以同步的对象。也许是这样的:
// 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(...)
循环。甚至sleep(1)
比旋转要好得多。你真的需要比~1ms更快地取消暂停吗?但是等待/通知是最有效的。
因为它与同步无关,我不想使用等待/通知。
正如@Jon 所提到的,由于您试图在两个线程之间进行通信,因此这里需要某种同步。当然,您需要进行内存同步,否则任何更新pauseFlag
都不能保证在线程之间共享。这是由 on 的volatile
原语处理的pauseFlag
。通过使用等待/通知(需要synchronized
),您的代码可以更有效地唤醒。