Утилита метода Future.cancel (boolean)

Я просто изучал пакет java.util.concurrent.

Я узнал, что класс « Future » имеет метод boolean cancel (boolean mayInterruptIfRunning)

Прилагаю тестовый код, который я написал:

package com.java.util.concurrent;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;

public class FutureTester {

/**
 * @param args
 * @throws InterruptedException
 */
public static void main(String[] args) throws InterruptedException {
    // TODO Auto-generated method stub
    int poolCnt = 1;
    Callable<NumberPrinter> numberPrinter = null;
    ScheduledThreadPoolExecutor schPool = new ScheduledThreadPoolExecutor(
            poolCnt);
    ScheduledFuture<NumberPrinter>[] numPrinterFutures = new ScheduledFuture[poolCnt];
    FutureTask<NumberPrinter>[] futureTask = new FutureTask[poolCnt];

    for (int i = 0; i < poolCnt; i++) {
        numberPrinter = new NumberPrinter();
        futureTask[i] = new FutureTask<NumberPrinter>(numberPrinter);

        /*
         * numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool
         * .schedule(futureTask[i], 0, TimeUnit.MILLISECONDS);
         */
        numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool
                .submit(futureTask[i]);
    }

    //Thread.sleep(30);

    if (numPrinterFutures.length > 0) {

        System.out.println("Task completed ? "
                + numPrinterFutures[0].isDone());

        System.out.println("Task cancelled ? "
                + numPrinterFutures[0].cancel(true));

        System.out.println("Is task cancelled ? "
                + numPrinterFutures[0].isCancelled());
    }
}

}

class NumberPrinter implements Callable<NumberPrinter> {

private int counter = 10;

@Override
public NumberPrinter call() throws Exception {
    // TODO Auto-generated method stub

    while (counter > 0) {
        if (Thread.interrupted()) {/*OUCH !!!*/
            return null;
        }
        System.out.println("counter = " + (counter--));
    }

    return this;
}

}

Сначала я предполагал, что отмена задача также остановит выполнение запущенного потока ( часть «OUCH» НЕ включена ). Но я получил следующий результат:

counter = 10
Task completed ? false
counter = 9
Task cancelled ? true
counter = 8
Is task cancelled ? true
counter = 7
counter = 6
counter = 5
counter = 4
counter = 3
counter = 2
counter = 1

При дальнейшем чтении самого stackoverflow было сказано, что

  1. Метод «cancel» может останавливать только «не запущенные» задания (что противоречит описанию метода api)
  2. Метод cancel просто прерывает запущенный поток, который затем должен вернуться из метода run ()

Следовательно, я включил часть 'OUCH' - цикл while, проверяющий прерывание ; результат был следующим:

Task completed ? false
counter = 10
Task cancelled ? true
Is task cancelled ? true

ВОПРОС:

Если предполагается, что напишите что-нибудь аналогичное части «OUCH», чтобы остановить запущенный поток, какова полезность / значение метода отмены. Как обертывание вызываемого объекта в FutureTask помогает, если поток не может быть остановлен с помощью отмены? Какую конструктивную / концептуальную / логическую часть я упускаю из виду?

37
задан skaffman 2 March 2012 в 16:11
поделиться