Java долго выполняющаяся задача Прерывание потока против флага отмены

В данной сборке может быть любое количество пространств имен, и ничто не требует, чтобы все они начинались с общего корня. Лучшее, что вы могли бы сделать, это отразить все типы сборки и создать список уникальных пространств имен, содержащихся в нем.

14
задан Jeff Storey 16 December 2009 в 14:14
поделиться

4 ответа

Прерывание вытесняет поток из списка указанных условий ожидания. Ваш собственный флаг отмены не будет. Если вы хотите прервать ожидание ввода-вывода и событий, используйте прерывание. В противном случае используйте свой собственный.

6
ответ дан 1 December 2019 в 09:32
поделиться

One problem with using interrupt is that if you do not control all code being executed, you run the risk of the interrupt not working "properly" because of someone else's broken understanding of how to handle interrupts in their library. That is the API invisibly exports an API around its handling of interrupts which you become dependent on.

In your example, suppose doSomeWork was in a 3rd-party JAR and looks like:

public void doSomeWork() {
    try { 
        api.callAndWaitAnswer() ; 
    } 
    catch (InterruptedException e) { throw new AssertionError(); }
}

Now you have to handle an AssertionError (or whatever else the library you are using might throw). I've seen experienced developers throw all sorts of nonsense on receiving interrupts! On the other hand, maybe the method looked like this:

public void doSomeWork() {
    while (true) {
        try { 
            return api.callAndWaitAnswer() ; 
        } 
        catch (InterruptedException e) { /* retry! */ }
    }
}

This "improper handling" of interrupt causes your program to loop indefinitely. Again, don't dismiss this as ridiculous; there are a lot of broken interrupt handling mechanisms out there.

At least using your own flag will be completely invisible to any 3rd-party libraries.

21
ответ дан 1 December 2019 в 09:32
поделиться

Это зависит от реализации doSomeWork () . Это чистое вычисление или оно (в любой момент) связано с блокировкой вызовов API (например, ввода-вывода)? Согласно ответу bmargulies , многие API-интерфейсы блокировки в JDK являются прерываемыми и распространяют прерванное исключение вверх по стеку.

Итак, если работа влечет за собой потенциально блокирующие действия, вам необходимо принять во внимание прерывания , даже если вы решили управлять процессом с помощью флага, и должны соответствующим образом улавливать и обрабатывать / распространять прерывания.

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

1
ответ дан 1 December 2019 в 09:32
поделиться

Я думаю, что в большинстве случаев это вопрос предпочтений. Лично я бы выбрал флаг ручной работы. Это дает вам больше контроля - например, таким образом вы убедитесь, что ваш поток не оставляет какой-либо другой объект в несогласованном состоянии. Кроме того, если производительность действительно критична, имейте в виду, что использование исключений имеет накладные расходы (даже если они незначительны в 99% случаев).

0
ответ дан 1 December 2019 в 09:32
поделиться