java - 线程似乎会在一段时间后自杀?
问题描述
我对线程非常陌生,在我的代码中使用线程时遇到以下问题。
在按钮上单击我正在启动一个运行特定任务的线程,并且该任务正在系统后台运行。我在线程内使用 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();
}
解决方案
我猜 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
。
推荐阅读
- wpf - 如何在 Windows 中创建后台进程应用程序?
- angular - 基于条件的动态验证
- java - 运行 java 时,Gradle 任务运行以非零退出值 100 完成
- shell - 如何自动化终端输入/命令?
- java - 强制统一构造函数和方法注释值?
- qt - 将 .mbtiles 转换为 .png 图像
- android - Godot 3.2 不会在编辑器设置中接受我的自定义构建 Sdk 路径
- javers - JaVers - 通过复合键检索审计更改
- google-bigquery - 为什么 BigQuery BI 引擎不使用所有预留?
- asp.net-mvc - 当我尝试在可能的主视图中渲染部分视图时遇到问题