java - Thread.Interrupt() 在 Android 中没有按预期工作?
问题描述
这是我的代码:
调用中断确实会停止线程,但只是一瞬间,线程立即继续,但为什么呢?我目前对这个问题的解决方案是使用 ArrayList 来管理线程,并遍历 ArrayList 来停止线程。虽然这行得通,但肯定不好。任何人都可以帮助我吗?
private Thread thread;
private static final String TAG = "StoragePresenter";
public void refreshVolumes(boolean isRunning) {
if (isRunning) {
Handler handler = new Handler();
Runnable runnable = () -> {
while (!thread.isInterrupted()) {
Log.d(TAG, "refreshVolumes: thread.isInterrupted? above while " + thread.isInterrupted());
try {
Thread.sleep(refreshDelay);
Log.d(TAG, "refreshVolumes: in TRY ---> " + Thread.currentThread().getName()); //Thread -> 9
} catch (InterruptedException ignored) {
}
Log.d(TAG, "refreshVolumes: in runnable WHILE ---> " + Thread.currentThread().getName());
handler.post(this::getVolumes);
}
};
thread = new Thread(runnable);
Log.d(TAG, "refreshVolumes: start thread's name -> " + thread.getName());
thread.start(); // Thread -> 9 started
} else {
Log.d(TAG, "refreshVolumes: interrupt thread's name -> " + thread.getName());
thread.interrupt(); // Thread -> 9 interrupted
Log.d(TAG, "refreshVolumes: thread.isInterrupted? " + thread.isInterrupted());
Log.d(TAG, "refreshVolumes: thread.isInterrupted? 2x " + thread.isInterrupted());
}
}
日志输出:
////////////////////////////////////
called refreshVolumes(true)
////////////////////////////////////
08-09 17:41:29.687 924-1811/? I/ActivityManager: START u0 {cmp=com.xxxxxxxxx.android.dev/com.xxxxxxxxx.app.ui.main.settings.storage.StorageActivity} from uid 10293
08-09 17:41:29.767 26451-26451/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: start thread's name -> Thread-9
08-09 17:41:29.768 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? above while false
08-09 17:41:29.927 924-995/? I/ActivityManager: Displayed com.xxxxxxxxx.android.dev/com.xxxxxxxxx.app.ui.main.settings.storage.StorageActivity: +210ms
08-09 17:41:33.269 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
refreshVolumes: in runnable WHILE ---> Thread-9
08-09 17:41:33.271 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? above while false
08-09 17:41:36.772 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
refreshVolumes: in runnable WHILE ---> Thread-9
08-09 17:41:36.773 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? above while false
08-09 17:41:40.274 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
refreshVolumes: in runnable WHILE ---> Thread-9
08-09 17:41:40.275 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? above while false
08-09 17:41:43.776 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
refreshVolumes: in runnable WHILE ---> Thread-9
08-09 17:41:43.777 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? above while false
08-09 17:41:47.278 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
08-09 17:41:47.279 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in runnable WHILE ---> Thread-9
08-09 17:41:47.280 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? above while false
08-09 17:41:50.780 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
refreshVolumes: in runnable WHILE ---> Thread-9
refreshVolumes: thread.isInterrupted? above while false
////////////////////////////////////
called refreshVolumes(false)
////////////////////////////////////
08-09 17:41:50.861 26451-26451/com.xxxxxxxxx.android.dev
D/StoragePresenter: refreshVolumes: interrupt thread's name -> Thread-9
08-09 17:41:50.862 26451-26451/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? true
refreshVolumes: thread.isInterrupted? 2x false
08-09 17:41:50.862 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in runnable WHILE ---> Thread-9
refreshVolumes: thread.isInterrupted? above while false
08-09 17:41:54.362 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
08-09 17:41:54.363 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in runnable WHILE ---> Thread-9
08-09 17:41:54.376 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? above while false
08-09 17:41:57.878 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
refreshVolumes: in runnable WHILE ---> Thread-9
08-09 17:41:57.879 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? above while false
08-09 17:42:01.380 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
refreshVolumes: in runnable WHILE ---> Thread-9
08-09 17:42:01.381 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? above while false
08-09 17:42:04.882 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
refreshVolumes: in runnable WHILE ---> Thread-9
08-09 17:42:04.883 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: thread.isInterrupted? above while false
08-09 17:42:08.384 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
08-09 17:42:08.385 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in runnable WHILE ---> Thread-9
refreshVolumes: thread.isInterrupted? above while false
08-09 17:42:11.886 26451-26676/com.xxxxxxxxx.android.dev D/StoragePresenter: refreshVolumes: in TRY ---> Thread-9
解决方案
Thread.sleep
抛出时InterruptedException
(由于在睡眠时被中断),它清除中断标志。如果您希望它以这种方式工作,您实际上应该处理InterruptedException
并使用该catch
块来跳出循环。
推荐阅读
- git - Github - 无法将我的代码推送到 github。它留在 gitbash 中
- c - 函数接收空字符串
- vb.net - 右键单击列表视图以显示 contextmenustrip,但弹出菜单出现在屏幕的不相关点
- google-apps-script - IFS 公式中的多个 COUNTIFS (FORMULA PARSE ERROR)
- ssl - Kafka 分区领导者 -1 仅通过 SSL
- node.js - cPanel 上的 Nodemailer
- html - 嵌入 html youtube 视频不可用
- mysql - 查找/添加缺失行的最快方法 (50K+)
- java - 以 30% 的概率生成布尔随机数
- laravel - Laravel 的 foreach 异常