Потоки Java: флаг завершения и исключение отлова - PullRequest
3 голосов
/ 01 апреля 2011

В темах, связанных с отменой, вы часто видите код, подобный этому

while (!shutdown) {
  .. do something, if a blocking call, then it will throw the interrupted exception
  try { .. some more ... } 
  catch (InterruptedException e) { 
    shutdown = true; 
  }
}

Что я хочу знать, так это или почему лучше, чем делать это

try {
  while (true) {
    .. do something, if a blocking call, then it will throw the interrupted exception
    if (Thread.interrupted()) throw new InterruptedException();
  }
} catch (InterruptedException e) {
  .. clean up, let thread end
}

Я вижу это так: в последнем случае вам вообще не нужно беспокоиться об отключении var.

Ответы [ 4 ]

7 голосов
/ 01 апреля 2011

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

Я бы не советовал использовать прерывание потока в качестве механизма отключения only .

(Точно так же будьте осторожны с тем, как вы обрабатываете общий флагКонечно, вам нужно сделать его поточно-ориентированным; в простых случаях, вероятно, будет достаточно переменной типа volatile.)

2 голосов
/ 01 апреля 2011

Вы не используете исключения как способ выхода из условия (по крайней мере, обычно, и лучше избегать этой практики.) Исключение для ... битов ... объявлять исключения, ошибки , ситуации и условия, которые обычно или потенциально плохие.

Завершение работы не является (как правило) условием ошибки, поэтому, по крайней мере с этой философской / проектной точки зрения, я бы предпочел первый вариант с использованием переменной флага выключения.

Кроме того, флаг можно выводить как свойство только для чтения (скажем, как получатель). Затем компоненты, внешние по отношению к потоку, могут видеть, является ли поток все еще активным (если у них есть логика, которая законно зависит от этого.)

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

2 голосов
/ 01 апреля 2011

Я думаю, что второй способ чище. Вот хорошая статья на ту же тему, которая также указывает на некоторые соображения ввода / вывода, связанные с прерыванием потока. http://www.javaspecialists.eu/archive/Issue056.html

1 голос
/ 01 апреля 2011

Я бы посоветовал вам использовать, наконец, для очистки потока (как это всегда вызывается), а не для исключения, просто чтобы разорвать цикл.попробуйте

try {
  while (!Thread.interrupted()) {
    .. do something, if a blocking call, then it will throw the interrupted exception
  }
} catch (InterruptedException e) {
  // handle exception
} finally {
  .. clean up, let thread end
}
...