我尝试了许多不同的方法来立即停止使用 ExecutorService 启动的任务,但没有成功。
Future<Void> future = executorService.submit(new Callable<Void>(
public Void call () {
... do many other things here..
if(Thread.currentThread.isInterrupted()) {
return null;
}
... do many other things here..
if(Thread.currentThread.isInterrupted()) {
return null;
}
}
));
if(flag) { // may be true and directly cancel the task
future.cancel(true);
}
有时我需要在任务启动后立即取消任务,您可能会好奇为什么我要这样做,您可能会想象这样一个场景:用户不小心点击了“下载”按钮来启动“下载任务”,然后他立即想要取消该操作,因为这只是意外点击。
问题是调用后future.cancel(true),任务不会停止并且Thread.currentThread.isInterrupted()仍然返回false我无法知道任务是从 call() 方法内部停止的。
我正在考虑设置一个标志,例如取消=真在调用 future.cancel(true) 并在 call() 方法中不断检查该标志之后,我认为这是一个 hack,代码可能非常难看,因为用户可以同时启动多个任务。
有没有更优雅的方式来实现我想要的?
EDIT:
这真让我抓狂。我现在已经在这个问题上花了将近一天的时间了。我将尝试对我面临的问题进行更多解释。
我执行以下操作来启动 5 个任务,每个任务将启动 5 个线程来下载文件。然后我停止所有 5 个任务立即地。对于下面的所有方法调用,我启动一个线程(ExecutorService.submit(task))以使其异步,正如您可以从方法的后缀中看出的那样。
int t1 = startTaskAysnc(task1);
int t2 = startTaskAysnc(task2);
int t3 = startTaskAysnc(task3);
int t4 = startTaskAysnc(task4);
int t5 = startTaskAysnc(task5);
int stopTaskAysnc(t1);
int stopTaskAysnc(t2);
int stopTaskAysnc(t3);
int stopTaskAysnc(t4);
int stopTaskAysnc(t5);
in 启动任务Aysnc(),我只是发起一个到远程服务器的套接字连接来获取文件的大小(这肯定需要一些时间),成功获取文件大小后,我将启动 5 个线程来下载文件的不同部分。如下(代码被简化以使其更易于理解):
public void startTaskAsync(DownloadTask task) {
Future<Void> future = executorService.submit(new Callable<Void>(
public Void call () {
// this is a synchronous call
int fileSize = getFileSize();
System.out.println(Thread.currentThread.isInterrupted());
....
Future<Void> futures = new Future<Void>[5];
for (int i = 0; i < futures.length; ++i) {
futures[i] = executorService.submit(new Callable<Void>(){...});
}
for (int i = 0; i < futures.length; ++i) {
futures[i].get(); // wait for it to complete
}
}
));
synchronized (mTaskMap) {
mTaskMap.put(task.getId(), future);
}
}
public void stopTaskAysnc(int taskId) {
executorService.execute(new Runnable(){
Future<Void> future = mTaskMap.get(taskId);
future.cancel(true);
});
}
我注意到一种奇怪的行为,在我为所有 5 个任务调用 stopTaskAsync() 后,总会有至少一个任务被执行stopped(即 Thread.currentThread.isInterrupted() 返回 true),其他 4 个任务继续运行。
我通过设置 UncaughtExceptionHandler 尝试了您的建议,但没有任何结果。
EDIT:
这个问题在这个链接中得到了解决:无法停止使用 ExecutorService 启动的任务