Future.cancel и ReentrantLocks - PullRequest
       14

Future.cancel и ReentrantLocks

0 голосов
/ 28 апреля 2011

Сценарий

У меня есть этот класс, скажем, Foo, единственное задание которого - последовательно выполнить набор задач.Звучит просто, правда?Ну, все этих задач выполняются в своем собственном отдельном потоке .Вместо простого вызова Thread.join() для каждой задачи, чтобы обеспечить последовательное выполнение, он использует ReentrantLock и Condition.Например,

public class Foo
{
    private final Lock lock;
    private final Condition condition;
    private Future<?> task;

    public Foo()
    {
        lock = new ReentrantLock();
        condition = lock.newCondition();

        run();
    }

    /**
     * Runs Foo
     */
    public void run()
    {
        Runnable runnable = new Runnable()
        {
            @Override
            public void run()
            {
                lock.lock();
                try
                {
                    // do tasks
                }
                finally
                {
                    lock.unlock();
                }

            }
        };

        // Submit task
        task = Executors.newSingleThreadExecutor().submit(runnable);
    }

    /**
     * Blocks execution until signal is received
     */
    public void waitForNotification()
    {
        try
        {
            condition.await();
        }
        catch (InterruptedException e)
        {
        }
    }

    /**
     * Gets the lock
     * 
     * @return Lock
     */
    public final Lock getLock()
    {
        return lock;
    }

    /**
     * Gets the condition
     * 
     * @return Condition
     */
    public final Condition getCondition()
    {
        return condition;
    }

    /**
     * Gets the sender's task
     * 
     * @return Task
     */
    public Future<?> getTask()
    {
        return task;
    }
}

После каждой задачи вызывается waitForNotification() и ждет другой класс, скажем Bar, чтобы разбудить его .Единственное задание для Bar заключается в обработке ответа, который сообщает приложению, прошла ли задача 1024 * или с ошибкой .При этом он будет выполнять одно из двух действий:

  1. Отмена потока (в целом getTask().cancel)
  2. Wake нить (то есть getCondition().signal)

Элемент 2 работает просто отлично, , но Элемент 1 не .Например,

public class Bar
{
    private Foo foo;

    // doesn't work!
    public void handleFailed()
    {
        // Cancel task
        foo.getTask().cancel(true)
    }

    public void handlePassed()
    {
         // Signal waiting Foo
         foo.getLock().lock();
         try
         {
            foo.getCondition().signal();
         }
         finally
         {
            foo.getLock().unlock();
         }
    }
}

Вместо отмены потока просто кажется, что прерывает это, что заставляет Foo продолжить его выполнение.Извините за многословие, но я хотел дать вам, ребята, четкую картину.Есть предложения?

Ответы [ 2 ]

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

AFAIK, потоки не поддерживают понятие "отмена" из коробки. Вы должны запечь логику, чтобы «отменить» ваши конкретные задачи, когда ваш поток прерывается. Обычно это делается путем проверки состояния прерывания потока при запуске вашей задачи / задания и выхода из него, если для состояния установлено значение true (что происходит при вызове прерывания).

Пример фрагмента , который может помочь вам. Также прочитайте, Чисто закрывая темы .

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

Если задача не прервана при прерывании, флаг будет только установлен и останется установленным, пока задача не завершится или не решит остановиться.

Возможный дубликат http://www.google.co.uk/search?q=how+do+I+stop+a+thread+in+Java 28 000 000 результатов.

...