Будущее задание ExecutorService не отменяется

Я помещаю свои фьючерсы из ExecutorService в хэш-карту. Позже я могу позвонить в Futures и отменить его из хэш-карты. Хотя результат верен, позже я установил точки останова в процедуре Callable, как будто Future cancel () не дало эффекта. Я думаю, что это может быть случай двух разных ссылок здесь (даже при том, что идентификаторы ссылок указаны как одинаковые при указании точки останова), но мне было интересно, могут ли некоторые эксперты вмешаться. Вот как выглядит код:

ExecutorService taskExecutor = Executors.newCachedThreadPool();
Map <String, Future<Object>> results = new HashMap <String, Future<Object>>();      

Future<Object> future = taskExecutor.submit(new MyProcessor(uid));
results.put(uid, future);

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

public static synchronized boolean cancelThread(String uid) {
    Future<Object> future = results.get(uid);
    boolean success = false;
    if (future != null) {
        success = (future.isDone() ? true : future.cancel(true));
        if (success)
            results.remove(uid);
    }
    return success;     
}

Но я все еще сталкиваюсь с "неотмененной" путь в MyProcessor.call () после того, как вызывается future.cancel () - то есть он на самом деле не отменяется.

Куда я иду с этим не так? Есть ли лучше было сделать это?

Ответы на вопрос(2)

Решение Вопроса

as if the Future cancel() had no effect.

Future.cancel(true) удаляет задание, которое находится в очереди и еще не запущено, но если задание уже запущено, оно эквивалентноThread.interrupt(), Это устанавливает бит прерывания в потоке и вызывает любоеsleep(), wait()и некоторые другие методыInterruptedException.

Важно понимать, что это делаетnot остановить поток. Вам необходимо активно проверять наличие флага прерывания в цикле потока или правильно обрабатыватьInterruptedException.

Смотрите мой SO ответ здесь для более подробной информации:

how to suspend thread using thread's id?

 22 июн. 2012 г., 17:03
Также связано с:stackoverflow.com/questions/6698977/…
 Ryan H22 июн. 2012 г., 18:15
Чтобы пояснить, это утверждение, которое я, вероятно, использую при запросе отмены, представляет собой PreparedStatement в базе данных: "stmt.execute ();" Так что я думаю, что я должен позволить базе данных закончить курс и потом проверять наличие прерываний.
 Ryan H22 июн. 2012 г., 18:03
Я вижу, что это имеет смысл - я не нахожусь в состоянии ожидания () в этот момент в Callable, так что это не вызывает InterruptedException для меня. К сожалению, я пытаюсь отменить один вызов оператора в базе данных, как только он уже запущен, так что в лучшем случае я могу поставить тест на то, прерывается ли поток впоследствии.
 23 июн. 2012 г., 00:27
Проблема в том, что @Ryan вы отправляетеRunnable в пул потоков. У него есть собственный поток, так что он использует только вашThread.run() метод. Если вам нужно переопределитьinterrupt() тогда вам нужно будет создавать собственные потоки и не использовать пул.
 Ryan H22 июн. 2012 г., 20:46
Итак, я изменил его на Runnable Thread вместо Callable, чтобы я мог переопределить метод interrupt () и в нем отменить мой оператор базы данных, используя stmt.cancel (); Однако, похоже, что Future.cancel (true) не может явно вызывать этот метод прерывания, так как я никогда не получаю его. Думал, у меня там что-то есть.

FutureTask :: boolean cancel(boolean mayInterruptIfRunning) будет выполнятьinterrupt на текущий рабочий поток.

public boolean cancel(boolean mayInterruptIfRunning) {
    if (!(state == NEW &&
          UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
              mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
        return false;
    try {    // in case call to interrupt throws exception
        if (mayInterruptIfRunning) {
            try {
                Thread t = runner;
                if (t != null)
                    t.interrupt();     ////////////HERE/////////////
            } finally { // final state
                UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
            }
        }
    } finally {
        finishCompletion();
    }
    return true;
}

JavaDoc говорит ниже дляinterrupt

public void interrupt()

Interrupts this thread. Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.

If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.

If none of the previous conditions hold then this thread's interrupt status will be set.

Interrupting a thread that is not alive need not have any effect.

Throws: SecurityException - if the current thread cannot modify this thread

To conclude; отменаFutureTask имеет влияние только в том случае, если поток заблокирован (при вызове wait (), ...), в противном случае ответственность за проверку несет разработчикThread.currentThread().isInterrupted() выйти; при выполнении неблокируемой операции.

Ваш ответ на вопрос