等待线程循环完成

发布于 2024-12-20 03:04:11 字数 736 浏览 6 评论 0原文

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

现在,无论我做什么,我都会僵住。可能摆脱僵局或诸如此类的情况; 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之前被调用等待,调用者将冻结。

我确信使用 synchronized 中包围的块可以解决问题,但我似乎无法获得正确的组合。

有什么想法吗?

I want to make a method that safely stops a thread running in a loop, allowing for the last loop to finish before returning control to the stopper.

Right now, no matter what I try, I freeze. Possibly out of deadlocks or whatnot; Java is not my usual environment, hence why this may be yet-another wait/notify question.

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...
    }
}

The problem with this approach (apart from the fact that I synchronize on this, but it's for the sake of example simplicity), is that if notify gets called before wait, the caller will freeze.

I'm sure that playing with the blocks I surround in synchronized could fix the problem, but I can't seem to get the right combination.

Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

樱&纷飞 2024-12-27 03:04:11

只需寻求真正简单的解决方案:

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()代码> 在线程上。

Just go for the real simple solution:

private volatile boolean isRunning = true;

@Override
public void run() {
    while (isRunning) {
        // Do work...
    }
}

public void stopThread() {
    isRunning = false;
}

that's basically what Thread.interrupted() does internally, so you can just use this as well:

@Override
public void run() {
    while (Thread.interrupted()) {
        // Do work...
    }
}

in which case you have to call interrupt() on the thread.

清风挽心 2024-12-27 03:04:11

我希望第二种方法是从与 run 方法不同的线程调用的。我打赌是这样的。

在这种情况下,将 isRunning=false 放置在同步块内就足够了。只有一个线程可以进入给定监视器上同步的块。

顺便说一句,不要调用 super.run(),它没有用,也不是一个好的编程习惯。

I hope the second method is called from a different thread that the one with the run method. I bet so.

In this case, placing the isRunning=false inside the synchronized block could be enough. Only one thread can enter a block synchronized on a given monitor.

Btw, don't call super.run(), it's useless and not a good programming habit.

佼人 2024-12-27 03:04:11

首先要开始的事情是运行易失性。

volatile boolean isRunning = true;

问题是java运行时做了一些优化,即使第一个线程更改了值,值也没有反映在其他线程中。

First thing to start with make isRunning volatile.

volatile boolean isRunning = true;

The problem is that java runtime do some optimization and value is not reflected in the other thread even though first thread changed the value.

悍妇囚夫 2024-12-27 03:04:11

找到了一个更简单的解决方案,它只是阻止在进行更改时检查 isRunning

boolean isRunning = true;

@Override
public void run() {
    while (true) {
        synchronized(this) {
            if (!isRunning) break;
        }

        // Do work...
    }
}

public void stopSafely() {
    synchronized(this) {
        isRunning = false;
    }
}

Found a much simpler solution, which simply prevents from checking isRunning when doing the change:

boolean isRunning = true;

@Override
public void run() {
    while (true) {
        synchronized(this) {
            if (!isRunning) break;
        }

        // Do work...
    }
}

public void stopSafely() {
    synchronized(this) {
        isRunning = false;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文