Поток Java - странный Thread.interrupted () и future.cancel (истинное) поведение

Я хочу управлять списком объектов фьючерсов, возвращенных моим 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 сборки

5
задан Nathan Kleyn 8 November 2011 в 04:26
поделиться

3 ответа

Имейте в виду, что Thread.inturebread () Возвращает текущее прерванное состояние , а затем очищает его , поэтому все будущие вызовы вернутся ложным. Вероятно, вы хотите, вероятно, Thread.CurrentThread (). IsiNturbepted () .

Также осознайте, что Future.cancel (true) обычно возвращается только False, если задача уже была завершена или отменена. Если он возвращает TRUE, это не гарантируют, что задача фактически будет отменена.

Что происходит в DOSHOURE () ? Это возможно, что runtimeeException возникает где-то из-за прерывания. У вас есть UnculexceptionHandler ? Если нет, вам нужно будет пройти ThreadFactory к исполнителям , который установит обработчик исключения и зарегистрировать любые пропущенные исключения.

6
ответ дан 13 December 2019 в 22:07
поделиться

По крайней мере, необходимо восстановить флаг прерывания, чтобы оповестить исполнителя taskExecutor о прерывании потока:

public String call() { 
    while (true) { 
        if (Thread.interrupted()) { 
            Thread.currentThread().interrupt();
            break; 
        } 
        doSomething(); 
    } 
} 
2
ответ дан 13 December 2019 в 22:07
поделиться

Потенциальная проблема, которую прерывания часто проглатываются. Так что где-то глубоко в дошутных () (или даже в классовой погрузке), прерывание может быть поймано, скажем, ждут () , а затем отбрасывается «небрежным» кодом. Прерывания злые, ИМО.

Может стоить проверку того, что все ваши задачи на самом деле работают во время отмены.

2
ответ дан 13 December 2019 в 22:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: