我对线程非常陌生,在代码中使用线程时遇到以下问题。
单击按钮后,我将启动一个运行特定任务的线程,并且该任务在系统后台运行。我在线程内使用 while 循环来检查是否通过单击另一个按钮来更改 volatile boolean 值以停止整个过程。问题是我必须添加一个空循环,否则看起来线程会自行停止并且不再检查 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();
}
您需要保留 boolean 标志来处理虚假唤醒
。如果满足条件,您将继续使用代码,否则您将返回等待通知。
请注意,该示例不处理任何可能发生的中断。
<小时/>您可能想要使用 AsyncTask.execute
而不是自己启动线程。
检查这个answer
.
关于java - 线程似乎在一段时间后就自杀了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58157095/