Java 等待线程循环完成
我想创建一个方法,安全地停止循环中运行的线程,允许在将控制返回到停止器之前完成最后一个循环 现在,无论我尝试什么,我都僵住了。可能摆脱了僵局或其他什么;Java不是我通常使用的环境,因此这可能是另一个等待/通知问题Java 等待线程循环完成,java,multithreading,wait,notify,Java,Multithreading,Wait,Notify,我想创建一个方法,安全地停止循环中运行的线程,允许在将控制返回到停止器之前完成最后一个循环 现在,无论我尝试什么,我都僵住了。可能摆脱了僵局或其他什么;Java不是我通常使用的环境,因此这可能是另一个等待/通知问题 boolean isRunning = true; @Override public void run() { super.run(); while (isRunning) { // Do work... } synchroniz
boolean isRunning = true;
@Override
public void run() {
super.run();
while (isRunning) {
// Do work...
}
synchronized(this) {
this.notify();
}
}
public void stopSafely() {
isRunning = false;
try {
synchronized(this) {
this.wait();
}
} catch (InterruptedException ex) {
// Handle...
}
}
这种方法的问题(除了我在this
上同步这一事实之外,但为了简化示例),是如果notify
在wait
之前被调用,调用方将冻结
我确信在synchronized
中使用我环绕的块可以解决问题,但我似乎无法得到正确的组合
有什么想法吗?找到了一个简单得多的解决方案,它可以简单地防止在进行更改时检查
是否正在运行:
boolean isRunning = true;
@Override
public void run() {
while (true) {
synchronized(this) {
if (!isRunning) break;
}
// Do work...
}
}
public void stopSafely() {
synchronized(this) {
isRunning = false;
}
}
我希望第二个方法是从使用run方法的线程调用的。我敢打赌
在这种情况下,将isRunning=false放在同步块内就足够了。只有一个线程可以进入给定监视器上同步的块
顺便说一句,不要调用super.run(),它没有用,也不是一个好的编程习惯。首先要做的是让isRunning变得不稳定
volatile boolean isRunning = true;
问题是java运行时进行了一些优化,而值并没有反映在另一个线程中,即使第一个线程更改了值。只需使用真正简单的解决方案:
private volatile boolean isRunning = true;
@Override
public void run() {
while (isRunning) {
// Do work...
}
}
public void stopThread() {
isRunning = false;
}
这基本上就是Thread.interrupted()
在内部所做的,所以您也可以使用它:
@Override
public void run() {
while (Thread.interrupted()) {
// Do work...
}
}
在这种情况下,您必须在线程上调用interrupt()
如果保留此选项,请使用更简单且等效的私有同步StopSafe(){isRunning=false;}。但是,像您这样同步整个run方法不是一个好主意。如前所述,这将使对StopSafe的任何调用都死锁,不是吗?您是对的,我为您的注释更改了该方法。请看编辑。此方法使用同步作为内存屏障。由于您实际上没有使用wait、notify或做任何需要原子性的事情,所以您应该使用@Voo的建议,即只使用volatile变量。