我有两种创建和停止线程的方法。但是,即使在调用第一个方法之后,线程仍然保持运行。 (我正在创建类的对象并从另一个类中调用它们。)
private Thread thread;
public void stopAlarm() {
Log.i(LOG_TAG, "stopAlarm called");
sendAlarm = false;
if (!thread.equals(null)) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void triggerAlarm() {
Runnable alarmTest = new Runnable() {
@Override
public void run() {
while (sendAlarm) {
Log.i(LOG_TAG, String.valueOf(sendAlarm));
}
}
};
thread = new Thread(Test);
thread.start();
}
当调用stopAlarm时,线程始终为null,尽管在调用triggerAlarm(线程正在运行)之后调用它。
答案 0 :(得分:1)
根据您的操作系统,您可能会发现让您的帖子volatile可以解决此问题。
private volatile Thread thread;
但是 - 有更好的方法可以做到这一点。一个非常有用的方法是使用一个小的(只有一个条目)BlockingQueue
,它由正在运行的线程poll
编写。
// Use a BlockingQueue to signal the alarm to stop.
BlockingQueue<String> stop = new ArrayBlockingQueue<>(1);
public void stopAlarm() {
stop.add("Stop");
}
public void triggerAlarm() {
new Thread(() -> {
try {
while (stop.poll(1, TimeUnit.SECONDS) == null) {
// Stuff
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
显然,您必须管理边缘情况,例如在没有警报运行时有人呼叫stopAlarm
的情况。
答案 1 :(得分:1)
您的问题是由线程范围引起的。当您在范围中创建具有相同变量的线程时,会创建线程范围,但您无法从外部世界更改这些变量。在android中管理runnables的最佳做法是使用Handler
。
Handler handler = new Handler();
Runnable alarmTest = new Runnable() {
@Override
public void run() {
Log.i(LOG_TAG, String.valueOf(sendAlarm));
handler.post(alarmTest, 5000); //wait 5 sec and run again
//you can stop from outside
}
};
定义之后,为了启动runnable:
handler.post(alarmTest,0); //wait 0 ms and run
为了停止runnable:
handler.removeCallbacks(alarmTest);
编辑:带循环的等待语句
编辑:完整的解决方案
Handler handler = new Handler();
Runnable alarmTest = new Runnable() {
@Override
public void run() {
Log.i(LOG_TAG, String.valueOf(sendAlarm));
handler.post(alarmTest, 5000); //wait 5 sec and run again
//you can stop from outside
}
};
public void stopAlarm() {
Log.i(LOG_TAG, "stopAlarm called");
handler.removeCallbacks(alarmTest);
}
public void triggerAlarm() {
handler.post(alarmTest,0); //wait 0 ms and run
}