2012-06-22 13 views
6

私はExecutorServiceからMy Futuresをハッシュマップにプッシュします。後で、私はハッシュマップ内から先物についてキャンセルを呼び出すことがあります。結果はtrueですが、私は後でcancel()が効果を持たないかのように、Callableプロシージャ内でブレークポイントを後で押しました。私は(ブレークポイント時に参照IDが同じとして列挙されているにもかかわらず)を、それはここでは2つの異なる参照の場合であるかもしれないと思うが、一部の専門家は、チャイムができればと思いまして。ここのコードは次のようになります。ExecutorServiceの今後のタスクが本当にキャンセルされない

ExecutorService taskExecutor = Executors.newCachedThreadPool(); 
Map <String, Future<Object>> results = new HashMap <String, Future<Object>>();  

Future<Object> future = taskExecutor.submit(new MyProcessor(uid)); 
results.put(uid, future); 

私は(それは彼らが渡されなどのタスクを提出するループです)処理を続行できるよう、後で私は、このメソッドを呼び出すことにより、外部ソースからのキャンセルを試みることがあります。

public static synchronized boolean cancelThread(String uid) { 
    Future<Object> future = results.get(uid); 
    boolean success = false; 
    if (future != null) { 
     success = (future.isDone() ? true : future.cancel(true)); 
     if (success) 
      results.remove(uid); 
    } 
    return success;  
} 

しかし、私はまだ「非出会いfuture.cancel()が呼び出された後、MyProcessor.call()内の "キャンセルされた"パスが呼び出されます。つまり、実際にキャンセルされていません。

どこが違うのですか?これを行う方がいいですか?

答えて

13

私は後でキャンセル()が効果がないかのように、Callableプロシージャ内でブレークポイントを後で押します。

Future.cancel(true)

はキューにある、まだ稼働していないが、ジョブがすでに実行されている場合、それは Thread.interrupt()と同等の処理を行い、ジョブを削除します。これにより、スレッドの割り込みビットが設定され、 sleep(), wait()などのメソッドが InterruptedExceptionをスローします。

ではなく、スレッドを停止することが重要です。スレッドループ内の割り込みフラグを積極的にチェックするか、InterruptedExceptionを適切に処理する必要があります。

how to suspend thread using thread's id?

+0

また、関連している:http://stackoverflow.com/questions/6698977/thread-interrupt-will-it-cancel-oncoming-wait-call – Gray

+0

私はそれが意味を理解する - 私は待っていない)ステータスを呼び出すことができるので、私のためにInterruptedExceptionを投げているわけではありません。残念ながら、私が取り消そうとしているのは、すでに開始されているデータベースに対する単一のステートメント呼び出しです。したがって、スレッドが後で中断されたかどうかのテストを行うことができます。 –

+0

これを明確にするために、キャンセルが要求されたときのステートメントをPreparedStatementというデータベースに入れます: 'stmt.execute();' 私は、データベースをコース終了し、後で割り込みをチェックする必要があると思います。 –

0

FutureTask :: boolean cancel(boolean mayInterruptIfRunning)、現在実行中のスレッドにinterruptを実行します。

は私のSO詳細はこちらをお答えください。

FutureTask.java 
public boolean cancel(boolean mayInterruptIfRunning) { 
    if (!(state == NEW && 
      UNSAFE.compareAndSwapInt(this, stateOffset, NEW, 
       mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) 
     return false; 
    try { // in case call to interrupt throws exception 
     if (mayInterruptIfRunning) { 
      try { 
       Thread t = runner; 
       if (t != null) 
        t.interrupt();  ////////////HERE///////////// 
      } finally { // final state 
       UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); 
      } 
     } 
    } finally { 
     finishCompletion(); 
    } 
    return true; 
} 

JavaDocinterrupt

ます。public void割り込み()

このスレッドに割り込みについては、以下を言います。現行の スレッドがそれ自体を中断していない場合(常に許可されている場合を除く)、このスレッドの checkAccessメソッドが呼び出され、 SecurityExceptionがスローされる可能性があります。

オブジェクトクラスまたはjoin()のwait()、wait(long)、 またはwait(long、int)メソッドの呼び出しでこのスレッドがブロックされた場合は、 joinこのクラスの のメソッドは、その割り込みステータスがクリアされ、 はInterruptedExceptionを受け取ります。このスレッドは、チャネルが閉じられます割り込み チャネル上でI/O操作でブロックされている場合

、スレッドの割り込みステータス が設定され、スレッドはClosedByInterruptExceptionを受け取ります。

このスレッドがセレクタにブロックされている場合は、スレッドの割り込み ステータスが設定され、それがセレクタの wakeupメソッドが呼び出されたかのように、おそらくゼロ以外の値で、選択 操作からすぐに戻ります。

上記のいずれの条件も成立しない場合、このスレッドの割り込み ステータスが設定されます。

生きていないスレッドを中断することは効果がありません。

例外:SecurityException - 現在のスレッドがを締結するには、この スレッド

を変更できない場合。 FutureTaskのキャンセルは、スレッドが(wait()、...)の呼び出しでブロックされている場合にのみ影響します。それ以外の場合は、終了するようにThread.currentThread().isInterrupted()をチェックする開発者の責任です。ブロックされていない操作を実行します。

関連する問題