在Android中停止线程

时间:2011-12-07 11:05:19

标签: android multithreading

我有以下代码,有时“decode()”函数不会停止,具体取决于它正在解码的文件。如果需要花费很多时间,我只想停止解码。我试过调用interrupt()函数,但似乎“decode()”函数没有停止。 我可以知道停止decode()函数的正确方法是什么?

Thread decodeThread = new Thread(new Runnable() {
     public void run() {
         decode();
     }
});

此线程不循环。函数“decode()”只是不返回。

任何反馈都将不胜感激。

谢谢, artsylar

3 个答案:

答案 0 :(得分:1)

我认为,你不会强行停止线程,因为它很危险。你设置了一个标志,告诉有问题的线程在受控环境下退出它的线程循环。

你的线程循环看起来像这样:

void run() {
  while (shouldContinue) {
    doThreadWorkUnit();
  }
}

在其他地方设置shouldContinue volatile variable并等待线程完成:

...
thread.shouldContinue = false;
thread.join();
...

编辑:(这是Sephy的支持)

停止线程的建议方法。

现在线程的stop()suspend()等方法已被弃用安全终止线程的唯一方法就是让它退出run()方法,也许是通过未经检查的异常。在Sun的文章Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?中,有一些关于如何在不使用不安全的弃用方法的情况下停止线程的建议。

方法建议使用volatile stop flag(下面的代码中的闪光灯)

private volatile Thread blinker;
public void stop() {
    blinker = null;
}
public void run() {
    Thread thisThread = Thread.currentThread();
    while (blinker == thisThread) {
        try {
            thisThread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}

volatile关键字用于确保线程之间的快速通信。 “字段可能被声明为volatile,在这种情况下,线程必须在每次访问变量时将其字段的工作副本与主副本进行协调。此外,代表线程的一个或多个volatile变量的主副本上的操作由主存储器按照线程请求的顺序执行。“

答案 1 :(得分:1)

我建议调查AsyncTask,因为这会处理许多条件(例如在背景和UI线程之间做出区分)。例如:

AsyncTask<String, Void, String> task = new AsyncTask<String, Void, String>() {
    @Override
    protected String doInBackground(String... params) {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // The thread was interrupted
                return null;
            }
            if (isCancelled()) {
                return null;
            }
        }
        return "some output";
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();
        // TODO
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        // TODO
    }
};

您可以使用以下方式执行任务:

task.execute("some input");

使用以下方法取消任务:

task.cancel(true);

答案 2 :(得分:0)

检查一下: http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

特别是部分“如果线程没有响应Thread.interrupt怎么办?”和“我应该使用什么而不是Thread.stop?