Я пробовал много разных способов немедленно остановить задачу, которая запускается с использованием 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 ().
Я думаю об установке флага типа cancelled = true после вызова future.cancel (true)и постоянно проверяя этот флаг в методе call (), я думаю, что это хак, и код может быть очень уродливым, потому что пользователь может запустить много задач одновременно.
Есть ли более элегантный способ достижения того, чего я хочу?
РЕДАКТИРОВАТЬ:
Это действительно сводит меня с ума.Я потратил почти день на эту проблему сейчас.Я попытаюсь объяснить немного больше для проблемы, с которой я сталкиваюсь.
Я делаю следующее, чтобы запустить 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);
в startTaskAysnc () , я просто инициирую сокет-соединение с удаленным сервером, чтобы получить размер файла (и это, безусловно, займет некоторое время), после успешного получения fileSize, я запусту 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);
});
}
Я заметил странное поведение, заключающееся в том, что после вызова stopTaskAsync () для всех 5 задач всегда будет хотя бы одназадача, которая получила остановлена (то есть Thread.currentThread.isInterrupted () возвращает true), а остальные 4 задачи продолжали выполняться.
И я попробовал ваши предложения, установив UncaughtExceptionHandler, но ничегоИсходя из этого.
РЕДАКТИРОВАТЬ:
Проблема была решена по этой ссылке: Не удается остановить задачу, которая запускается с использованием ExecutorService