シナリオ
私はこのクラスを持っています。たとえば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たかをアプリケーションに通知する応答を処理することです。そうは言っても、次の2つのいずれかを実行します。
- スレッドを完全にキャンセルgetTask().cancelします(つまり)
- スレッドをウェイクします(つまり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、実行が続行されます。冗長性については申し訳ありませんが、私は皆さんに明確な画像を提供したいと思いました。助言がありますか?