如何在Java中安全地停止和恢复线程?

时间:2012-08-08 01:04:54

标签: java multithreading thread-safety

我有一个运行的线程,我想停止,稍后恢复。我学会了不使用stop()等,因为这些已被弃用,并且下面的代码似乎成功停止了线程。它只是退出运行方法。现在,我该如何重新启动它?如果我调用start()方法,它说该线程仍在运行,那么在这种情况下会直接调用run()吗?会不会引起任何问题?顺便说一下,这适用于Android应用程序,如果这有任何区别。

private volatile stopThread;

public void stopButton() {
    // this is called when button is clicked
    // and thread is already started and running
    stopThread= true;
}

public void run() {

    while (!stopThread) {
        // do something here
    }

    stopThread=false;
}

编辑:它是一个在线程启动时启动的计时器,然后可以暂停并重新启动。所以timer是一个包含Thread对象的类(我已经使用SurfaceView扩展了类)。

3 个答案:

答案 0 :(得分:6)

安全停止和恢复线程的唯一安全方法是在线程正文中的相关点添加代码来处理它。 (不要使用已弃用的Thread stop / pause / resume,因为它们基本上是不安全的。)

使用特定于应用程序的标志或Thread.interrupt()机制,不使用恢复进行停止相对简单。后者可能更好,因为Java的一些同步和IO API都是中断感知的。但是,您确实遇到了许多现有库不能识别中断,或者没有正确处理InterruptedException的问题。

停止恢复更加棘手。您需要创建自己的类,如下所示:

public class PauseControl {
    private boolean needToPause;

    public synchronized void pausePoint() {
        while (needToPause) {
            wait();
        }
    }

    public synchronized void pause() {
        needToPause = true;
    }

    public synchronized void unpause() {
        needToPause = false;
        this.notifyAll();
    }
}

并在整个线程代码的相关位置添加对myPauseControl.pausePoint()的调用。请注意,这不允许您暂停“子”线程中的IO或活动,并且只会在您调用pausePoint方法的代码中暂停。此外,您需要注意通过暂停线程来保持创建问题,同时保持线程锁定其他内容,或者等待其他东西等待响应。

答案 1 :(得分:2)

Java 1.4文档通过使用suspend()resume()解释了为什么并提供了各种已弃用的Thread方法的替代方法,包括wait()notify()

在页面的中间位置查找标题What should I use instead of Thread.suspend and Thread.resume?

答案 2 :(得分:0)

不推荐使用Thread类的stop()方法,并且不安全,因为停止Thread会导致它解锁已锁定的所有监视器。这具有破坏性后果,因为处于不一致状态的任何对象(以前受监视器保护)现在可以被处于不一致状态的其他线程查看。这种行为可能很微妙,难以察觉。

您永远不会直接调用run()方法,如果使用volatile变量方法停止Thread,则Thread将具有TERMINATED。为了启动Thread,再次执行新的Thread()。start()。