2017-06-21 8 views
1

ステートレスEJBをRESTサービスとして公開しています。私のPOSTメソッドでは、私は、クライアント側からlongRunningBusinessMethod()の実行をキャンセルすることが可能となる行くにはどうすればよいJava:RESTサービスメソッドの実行をキャンセルします。

Result r = longRunningBusinessMethod(); 
//return data 

呼び出しますか? 私は、メソッドのスレッドを作成し、すべての実行スレッドをIDとともにハッシュテーブルに保持することを考えました。ユーザーはIDをPOSTしてスレッドを終了できます。しかし、よりよい解決策が必要であると確信しています。 助けていただければ幸いです。

答えて

1

「IDのテーブルを保持する」というラフなデザインが良いスタート地点だと思います。スレッドを外部で終了する代わりに、おそらくExecutorServiceをスレッドプールと共に使用してから、Map<ID, Future>を保持して、将来をキャンセルすることができます。 (また、それは非常に成功しまたはを完了するよう、各未来がマップから自身を削除することを確認すること。)

ます。また、それは、それが中断されていますかどうかを確認し、十分な場所が含まれるようにlongRunningBusinessMethodを実装する必要があります - 未来をキャンセルするとスレッドの割り込みフラグがセットされるだけで、実際にコードが実行されることはありません。長時間実行しているメソッドで既にInterruptedExceptionがスローされている場合は、それはそのままです。そうでない場合は、Thread.sleep(1)のようなダミーコールを追加するか、手動でThread.interrupted()を手動でチェックしてInterruptedExceptionを自分で投じる必要があります。

+0

それは私がそれをやる方法です。そして、スレッドを手動で終了しなければならないかどうかはわかりませんでした。短く関連した質問: 'Future#get(30、TimeUnit.Seconds)'を使用すると、タイムアウト例外がスローされた後も基本メソッドは実行されますか? – User9123

+0

タイムアウト例外がスローされると、基礎となるメソッド_may_がまだ実行されています。これは、あなたの 'longRunningBusinessMethod'を実行しているスレッドに' interrupted'フラグをセットするだけです。これにより、コードは割り込み可能な方法で書き込まれる必要があります。 –

1

作業スレッドを中断することは常に難しく、一般的にはお勧めしません。実行中のビジネスメソッドを変更して、実行を完了する必要があるかどうかを確認することです。例えば:

public void longRunningBusinessMethod(JobContext context){ 
    while(someCondition) { 
     if(shouldInterrupt(context)){ 
      log.info("Interrupting longRunningBusinessMethod"); 
      ... 
      <close all the resources and terminate the job> 
     } 
    } 
} 

shouldInterrupt(context)はそれにジョブIDとジョブコンテキストがかかりますし、それが中断されるべきかどうかをDBやキャッシュを聞いてきます。その後、REST APIを介してこの特定のジョブのDBまたはキャッシュの 'shouldInterrup'値を変更するのは簡単です。

関連する問題