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

我想创建一个方法,安全地停止循环中运行的线程,允许在将控制返回到停止器之前完成最后一个循环

现在,无论我尝试什么,我都僵住了。可能摆脱了僵局或其他什么;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
中使用我环绕的块可以解决问题,但我似乎无法得到正确的组合


有什么想法吗?

找到了一个简单得多的解决方案,它可以简单地防止在进行更改时检查
是否正在运行:

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变量。