等待线程循环完成

时间:2011-12-09 03:10:09

标签: java multithreading wait notify

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

现在,无论我尝试什么,我都会冻结。可能没有死锁或诸如此类的东西; 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中包含的块可以解决问题,但我似乎找不到正确的组合。

有什么想法吗?

4 个答案:

答案 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运行时做了一些优化,即使第一个线程改变了值,其他线程也没有反映出值。