我想制作一个安全地停止在循环中运行的线程的方法,允许在将控制权返回到塞子之前完成最后一个循环。
现在,无论我尝试什么,我都会冻结。可能没有死锁或诸如此类的东西; Java不是我通常的环境,因此为什么这可能是另一个等待/通知问题。
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
中包含的块可以解决问题,但我似乎找不到正确的组合。
有什么想法吗?
答案 0 :(得分:2)
只需寻找真正简单的解决方案:
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()
。
答案 1 :(得分:1)
我希望从另一个带有run方法的线程调用第二个方法。我敢打赌。
在这种情况下,将isRunning = false放在synchronized块中就足够了。只有一个线程可以进入在给定监视器上同步的块。
不过,不要打电话给super.run(),它没用,也不是一个好的编程习惯。答案 2 :(得分:0)
找到了一个更简单的解决方案,它可以防止在进行更改时检查isRunning
:
boolean isRunning = true;
@Override
public void run() {
while (true) {
synchronized(this) {
if (!isRunning) break;
}
// Do work...
}
}
public void stopSafely() {
synchronized(this) {
isRunning = false;
}
}
答案 3 :(得分:0)
首先要开始使用make isRunning volatile。
volatile boolean isRunning = true;
问题是java运行时做了一些优化,即使第一个线程改变了值,其他线程也没有反映出值。