首页 > 解决方案 > 线程似乎会在一段时间后自杀?

问题描述

我对线程非常陌生,在我的代码中使用线程时遇到以下问题。

在按钮上单击我正在启动一个运行特定任务的线程,并且该任务正在系统后台运行。我在线程内使用 while 循环来检查是否通过单击另一个按钮来更改 volatile bool 以停止整个过程。问题是我必须添加一个空循环,否则看起来线程会自行停止并且不再检查 while 条件。我认为这是非常低效的并且浪费了大量资源。

我正在添加代码的简短版本以使其不那么难以阅读。

知道为什么会发生这种情况以及如何提高代码的整体效率吗?

public void onClick(View view) {

    new Thread(new Runnable() {

           public void run() {
            //execute my task

           while(!stopThread) {
           // Without this empty loop the thread stops after a while

  }
           while(stopThread) { // stopThread is a volatile bool changed by another button click
           //Finish the task
           break;
    }
  }
  }).start();
  }

标签: javaandroid

解决方案


我猜 stopThread 的初始值为 false,这会导致您的第二个循环不被执行并且线程终止。

您可以在两个按钮之间共享一些锁定对象,而不是使用循环,而是使用等待和通知。检查this tutorial

一个可能的实现可能如下所示:

两个按钮都需要访问这两个变量:

Object lock = new Object();
volatile boolean stopThread = false;


onClick一个按钮的方法:

public void onClick(View view) {

    new Thread(new Runnable() {

        public void run() {

            // execute my task

            synchronized (lock) {
                // stopThread is a volatile boolean changed by another button click
                while (stopThread == false) {
                    lock.wait();
                }
            }

            // Finish the task
        }
    }).start();
}


第二个按钮的onClick方法:

public void onClick(View view) {

    new Thread(new Runnable() {

        public void run() {

            synchronized (lock) {

                stopThread = true;
                lock.notify();
            }
        }
    }).start();
}

您将希望保留布尔标志以处理spurious wakeups. 如果条件满足,您继续使用您的代码,否则您返回等待通知。

请注意,该示例不处理可能发生的任何中断。


您可能想要使用AsyncTask.execute而不是自己启动线程。
检查这个answer


推荐阅读