0

シナリオ

私はこのクラスを持っています。たとえば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たかをアプリケーションに通知する応答を処理することです。そうは言っても、次の2つのいずれかを実行します。

  1. スレッドを完全にキャンセルgetTask().cancelします(つまり)
  2. スレッドをウェイクします(つまり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、実行が続行されます。冗長性については申し訳ありませんが、私は皆さんに明確な画像を提供したいと思いました。助言がありますか?

4

2 に答える 2

1

AFAIK、スレッドは、箱から出して「キャンセル」するという概念をサポートしていません。スレッドが中断されたときに特定のタスクを「キャンセル」するには、ロジックを組み込む必要があります。これは通常、タスク/ジョブの実行時にスレッドの割り込みステータスをチェックし、ステータスがtrueに設定されている場合は正常に終了することによって行われます(これは、割り込みを呼び出すときに発生します)。

あなたを助けるかもしれないサンプルスニペットまた、スレッドをきれいにシャットダウンすることもお読みください。

于 2011-04-28T14:50:21.547 に答える
1

中断されたときにタスクが停止しない限り、フラグは設定され、タスクが終了するか停止するまで設定されたままになります。

http://www.google.co.uk/search?q=how+do+I+stop+a+thread+in+Java 28,000,000 の結果の重複の可能性があります。

于 2011-04-28T14:25:59.443 に答える