当前位置: 首页 > 知识库问答 >
问题:

线程似乎在一段时间后自杀?

周宏胜
2023-03-14

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

点击一个按钮,我就启动了一个运行特定任务的线程,这个任务在系统的后台运行。我在线程中使用了一个while循环来检查一个易失性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();
  }

共有1个答案

韶弘壮
2023-03-14

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

您可以在两个按钮之间共享一些锁对象,而不用使用循环,而是使用wait和notify。检查本教程。

可能的实现如下所示:

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

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


第一个按钮的点击方法:

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();
}

您需要保留布尔标志以处理虚假唤醒。如果条件已满,则继续使用代码,否则返回等待通知。

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

您可能需要使用AsyncTask。执行,而不是自己启动线程
检查此答案。

 类似资料:
  • 问题内容: 我正在尝试在我正在处理的Python项目中使用线程,但是线程似乎没有按照我的代码的预期运行。似乎所有线程都按顺序运行(即,线程2在线程1结束后开始,它们不是同时启动)。我编写了一个简单的脚本来对此进行测试,并且该脚本也按顺序运行线程。 这是我从运行它得到的输出: 循环的迭代次数更多时,观察到相同的行为。 我尝试搜索网络和较早的SO答案,但找不到任何有帮助的方法。有人可以指出这段代码有什

  • 问题内容: 我正在比较测试程序上的两个变体。两者都在具有四个内核的计算机上以4线程运行。 在“模式1”下,我非常类似于执行程序服务来使用池。我把一堆任务扔了进去。与普通的固定线程执行器服务相比,我获得了更好的性能(即使有对Lucene的调用,该调用在其中执行了一些I / O)。 这里没有分而治之。从字面上看,我知道 在“模式2”中,我向池提交一个任务,然后在该任务中调用ForkJoinTask.i

  • 问题内容: 我想在线程中运行一个进程(正在对一个大的数据库表进行迭代)。在线程运行时,我只希望程序等待。如果该线程花费的时间超过30秒,我想终止该线程并执行其他操作。通过杀死线程,我的意思是我希望它停止活动并优雅地释放资源。 我想这样做是通过最好的方式的和功能,以及。使用I,我可以让我的程序等待30秒等待线程完成,并且通过使用该函数,我可以确定线程是否完成了工作。如果尚未完成工作,则设置事件,并且

  • 在一个类中,在一个函数中,我创建了一个Tkinter画布。这个函数正在被另一个类调用,我希望Tkinter窗口弹出30秒,然后自动关闭。我有电话 但我犯了个错误 elf.tk.call('destroy',self.w)\u tkinter.TclError:无法调用“destroy”命令:应用程序已被销毁 那我怎么能让它自己关上呢?

  • 请查看Oracle规范-第5章。 这一行: 拓宽的基元转换不会丢失有关数值的整体大小的信息。 接下来,就在下面两行,这一行说震级信息可能会丢失。 从float到double的非strictfp加宽原语转换可能会丢失有关转换值的总体大小的信息。 这似乎是一个明显的矛盾;这是一个错误吗?

  • 问题内容: 这可能是一个重复的问题,但我没有找到想要的东西。我在UI活动中调用AsyncTask, 在doInBackground中调用需要时间的方法。如果一段时间后没有返回数据,我想中断该线程。以下是我尝试执行此操作的代码。 但这并不能在30秒后停止任务,事实上,这花费了更多时间。我也尝试过,但这也不起作用。 谁能告诉我该怎么做或如何在doInBackground中使用isCancelled()