2016-08-10 13 views
5

@Asyncアノテーションが付いているメソッドは、今後取り消すことができます。Spring Cancel @Async Task

私は@AsyncアノテーションでマークされたSpringメソッドを持っています。このメソッドは計算を実行し、最終的に結果を返します。私が見たすべての例では、このFutureを返すためにAsyncResultクラスを使用することをお勧めします。

@Async 
public Future<String> run() { 
    // ... Computation. Minutes pass ... 
    return new AsyncResult<String>("Result"); 
} 

私は以下の方法で別のコンポーネントから次のメソッドを呼び出します。例えば、このスレッドを直ちに取り消したいと思います。

Future<String> future = component.run(); 
future.cancel(true); 

この場合、スレッドは決してキャンセルされません。これは、AsyncResultのSpringインプリメンテーション:https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java#L71を見ているので、このメソッドは実際には1つのことをしないためです。単にスレッドを取り消すことができないというfalseを返します。これは私の問題です。 @Asyncメソッドで作成されているスレッドをキャンセルするにはどうすればよいですか? Springで作成された内部スレッドへのアクセス権がありません - キャンセルする方法はありませんか?

+0

これらの2つの回答[ここ](http://stackoverflow.com/questions/21084195/spring-async-cancel-and-start)と[ここ](http://stackoverflow.com/questions/35798987/)を確認してください。 stop-an-async-spring-method-from-caller-class)、あるいは '@Async'アノテートされたメソッドを扱うカスタム' ThreadPoolExecutor'を作成するか、実行中のタスクにバインドするカスタムの 'AsyncResult'を渡します。 – AntJavaDev

+0

これらの質問の答えは、実行中のスレッドに後で処理を停止するように指示するために、フラグ/セマフォの作成を記述しているようです。これは、Future.cancel()メソッドが自己定義された 'Runnable'内で行うようにスレッドを終了させることとは異なります。 カスタム 'ThreadPoolExecutor'がどのように見えるか少し説明できますか?私は自分のエグゼクティブも定義しているので、それを追加するのは難しくないか不便ではありません。 –

答えて

4

実際には、@Asyncは独自のバックグラウンドスレッドプールを使用しています。また、ExecutorサービスのFutureまたはshutdownNow()メソッドのcancel()メソッドが関係している限り、executor.shutdownNow() or future.cancel(true)を呼び出すことによって、直ちに進行中のスレッドが停止することはありません。これらの方法は、それぞれのスレッドで.interrupt()と呼ぶだけです。そしてinterruptsの保証なし即時効果があります。これはフラグを発行するので、スリープ状態または待機状態になるとスレッドは停止します。

タスクが中断を無視する場合、executor.shutdownNow() and future.cancel(true)はまったく同じ方法でexecutor.shutdown() and future.cancel(false)と同じ動作をします。

遅い操作またはブロックする操作を停止する方法が必要な場合は、長い/無限ループがある場合は、Thread.currentThread().isInterrupted()の条件を追加して、それが真(操作を終了)した場合は続行しないでください。

+0

素晴らしい。私は '@Async'メソッドのロジックを通して' Thread.interrupted() 'のブールチェックを追加しました。私が割り込みを検出した場合、私は安全にメソッドを分解して実行を取り消すことができます。 –

関連する問題