Future.cancel和ReentrantLocks

时间:2011-04-28 14:22:13

标签: java conditional-statements future reentrantlock

方案

我有这个课,让我们说Foo,其唯一的工作是顺序执行一组任务。听起来很简单吧?好吧,所有这些任务都是在他们自己的单独的线程中执行的。它不是简单地在每个任务上调用Thread.join()来确保顺序执行,而是使用ReentrantLockCondition。例如,

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的唯一作业是处理响应,通知应用程序任务是传递还是失败。话虽如此,它将做两件事之一:

  1. 完全取消主题(即getTask().cancel
  2. 唤醒主题(即getCondition().signal
  3. 第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 个答案:

答案 0 :(得分:1)

除非任务在中断时停止,否则该标志将被设置并保持设置,直到任务结束或决定停止。

可能重复http://www.google.co.uk/search?q=how+do+I+stop+a+thread+in+Java 28,000,000条结果。

答案 1 :(得分:1)

AFAIK,线程不支持开箱即用“取消”的概念。当线程中断时,您必须在逻辑中烘焙“取消”您的特定任务。这通常通过在运行任务/作业时检查线程的中断状态来完成,如果状态已设置为true(在调用中断时会发生这种情况),则会彻底退出。

A sample snippet 可能帮助您解决问题。另请阅读shutting down threads cleanly