FutureTask отменить () - PullRequest
       8

FutureTask отменить ()

2 голосов
/ 07 августа 2011

В основном у меня есть следующий фрагмент,


(let [task (FutureTask. fn)
      thr (Thread. task)]
  (.start thr)
  ;;wait for signal...
  (.cancel task true)
  (.stop thr))

Проблема в том, что время от времени отмена не работает, AFAICT отменяет причины и генерируется исключение, но какой-то фрагмент кода в строке ловит его? Есть ли верный способ отменить будущее задание?

fn - это функция, которая в основном выполняет серию длительных вычислений, поэтому я не могу выполнить циклическую проверку на наличие логического флага.

Ответы [ 3 ]

6 голосов
/ 07 августа 2011

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

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

while (notDone) {
    if (Thread.isInterrupted()){
      return; // we were cancelled (or interrupted in some other way)
    }

    doSomeHardWork()
}
1 голос
/ 10 августа 2011

Согласно моим (ограниченным) знаниям, не существует общего способа сделать это. Это потому, что у вас может быть одна бесперебойная, удаленная задача, у вас может быть одна задача, которая является чистой функцией и, следовательно, безопасной для уничтожения, у вас может быть много подзадач (как упомянул nerdytenor - проверка состояния isInterrupted между каждой), вы можете иметь смесь все, у вас может быть задача, которая, если ее убить, переведет другие задачи в состояние глобальной блокировки ... Насколько я знаю, вы должны сделать это сами.

Какие расчеты вы выполняете? Вы можете сделать что-нибудь внутри? Может быть, создать глобальную поточно-ориентированную таблицу toInterrupt и проверить в каждой подзадаче, будет ли отменена вся задача? Я знаю, что это очень не идиоматично, но пока не могу придумать ничего лучшего.

Или, если это действительно чисто функциональные вычисления, и вы действительно в этом уверены - убейте процесс / поток и надейтесь, что вы правы.

0 голосов
/ 03 октября 2013

Этот вопрос, вероятно, связан с Выполнение функции с таймаутом

Макрос работает для моего кода, код таймаута thunk равен здесь

(defmacro with-timeout [time & body]
  `(thunk-timeout (fn [] ~@body) ~time))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...