Я хочу управлять списком объектов фьючерсов, возвращенных моим TaskExecutor.
У меня есть что-то вроде этого
List<Future<String>> list
void process(ProcessThis processThis) {
for ( ...) {
Future<String> future = taskExecutor.submit(processThis);
list.add(future)
}
}
void removeFutures() {
for(Future future : list) {
assert future.cancel(true);
}
ProcessThis является задачей, которая реализует Вызываемый <Строка> и проверки на состояние Thread.interrupted()
public String call() {
while (true) {
if (Thread.interrupted()) {
break;
}
doSomething();
}
}
Теперь проблема состоит в том, что только подмножество параллельных Потоков возвращает 'true', когда Thread.interrupted () называют.
Утверждение в removeFutures () возвращает true для каждого будущего, которое удалено (я проверил isDone () и isCompleted () также.
Количество Потоков, которые прерваны, случайно. Более чем 15 рабочих Потоков иногда 13 прерваны, иногда 2...
Я действительно не понимаю, где проблема. если я называю future.cancel (верным), и это возвращает true..., и затем я проверяю Thread.interrupted (это называют только однажды), я ожидаю, что это возвратит true также.
Какая-либо идея того, что я пропускаю?
Я нахожусь на java 1.6.0_02-b05 сборки
Имейте в виду, что Thread.inturebread ()
Возвращает текущее прерванное состояние , а затем очищает его , поэтому все будущие вызовы вернутся ложным. Вероятно, вы хотите, вероятно, Thread.CurrentThread (). IsiNturbepted ()
.
Также осознайте, что Future.cancel (true)
обычно возвращается только False, если задача уже была завершена или отменена. Если он возвращает TRUE, это не гарантируют, что задача фактически будет отменена.
Что происходит в DOSHOURE ()
? Это возможно, что runtimeeException возникает где-то из-за прерывания. У вас есть UnculexceptionHandler ? Если нет, вам нужно будет пройти ThreadFactory к исполнителям
, который установит обработчик исключения и зарегистрировать любые пропущенные исключения.
По крайней мере, необходимо восстановить флаг прерывания, чтобы оповестить исполнителя taskExecutor о прерывании потока:
public String call() {
while (true) {
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
break;
}
doSomething();
}
}
Потенциальная проблема, которую прерывания часто проглатываются. Так что где-то глубоко в дошутных ()
(или даже в классовой погрузке), прерывание может быть поймано, скажем, ждут ()
, а затем отбрасывается «небрежным» кодом. Прерывания злые, ИМО.
Может стоить проверку того, что все ваши задачи на самом деле работают во время отмены.