делают ли метод cancel () и метод interrupt () дублирующую работу? - PullRequest
2 голосов
/ 14 сентября 2011

Я прочитал источник org.apache.nutch.parse.ParseUtil.runParser(Parser p, Content content).

Делают ли эти два вызова метода одно и то же:

Инструкция 1:

t.interrupt();

Инструкция 2:

task.cancel(true);

Источник org.apache.nutch.parse.ParseUtil.runParser(Parser p, Content content):

ParseCallable pc = new ParseCallable(p, content);
FutureTask<ParseResult> task = new FutureTask<ParseResult>(pc);
ParseResult res = null;
Thread t = new Thread(task);
t.start();
try {
  res = task.get(MAX_PARSE_TIME, TimeUnit.SECONDS);
} catch (TimeoutException e) {
  LOG.warn("TIMEOUT parsing " + content.getUrl() + " with " + p);
} catch (Exception e) {
  task.cancel(true);
  res = null;
  t.interrupt();
} finally {
  t = null;
  pc = null;
}
return res;

Ответы [ 2 ]

0 голосов
/ 15 сентября 2011

Здесь я хотел бы сделать вывод: когда мы передаем true в качестве аргумента FutureTask.cancel (), мы можем получить тот же эффект, что и interupt (). Зачем? Давайте заглянем в src метода cancel (). мы получили, что метод cancel () вызывает метод:

innerCancel(mayInterruptIfRunning);

внутри метода: innerCancel(mayInterruptIfRunning);, у нас могут быть следующие инструкции:

if (mayInterruptIfRunning) {
                Thread r = runner;
                if (r != null)
                    r.interrupt();
            }

Итак, в моем случае метод cancel () действительно вызывает interrupt ().

0 голосов
/ 14 сентября 2011

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

FutureTask.cancel() сообщает задаче, что ее больше не нужно запускать и (если true передается в качестве аргумента), будетпопытка прервать Thread, на которой в данный момент выполняется задача (если есть).

t.interrupt() попытка прервать Thread t.

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

Если в этот момент задание уже выполнено, то оба cancel() и interrupt() не будет иметь эффекта.

...