1

ユーザーからジョブのリストを受け取る呼び出しがあり、ユーザーが3つのジョブA、B、Cを投稿し、それらはすべて独自のスレッドAT、BT、CTで実行を開始し、これら3つのスレッドのいずれかがあれば監視を開始します。ジョブは失敗し、Bが失敗したと言います。停止するように、AとCに信号を送る必要があります。すべてのスレッドが停止したときは戻り、すべてが成功したときはtrue、1つがfalseに失敗した場合。

現在、チェックと50msのスリープを実行する1つの大きなwhileループがあります。これは機能しますが、スリープなしでこれを行うためのより良い方法があるのではないかと思っていました。 cpu queのですが、それでも60%前後のcpuを使いすぎています。

4

3 に答える 3

3

これはのユースケースのように聞こえますExecutorCompletionService

// wrap tasks A, B and C into runnables (or callables if you need some result):
Callable<Result> taskA = ...;
Callable<Result> taskB = ...;
Callable<Result> taskC = ...;

// create an ExecutorCompletionService
// to which you must pass an ExecutorService
// (choose one according to your precise use case)
// (the newCachedThreadPoolExecutor might not be a sensible choice)
ExecutorCompletionService e = new ExecutorCompletionService(Executors.newCachedThreadPoolExecutor());

Set<Future<Result>> futures = new HashSet<>();

// submit your tasks:
futures.add(e.submit(taskA));
futures.add(e.submit(taskB));
futures.add(e.submit(taskC));

// now call take() on the executor completion service,
// which will block the calling thread until the first task has completed
// either succesfully or abruptly (with an exception)
Future<Result> f = e.take();

この後、を呼び出すとf.get()、のインスタンスを取得するかResultExectutionException(実行によってスローされた例外をラップする)をスローします。どちらかがすぐに発生します(エグゼキュータ完了サービスのおかげで)。

次に、それに応じて対応します。f.get()例外をスローした場合は、セットから削除fし、futuresセットの他の要素(つまり、送信した他のタスク)を繰り返し処理し.cancel()ます。Callablesはキャンセル可能にコーディングする必要があります。そうしないと、toの呼び出しは.cancel()何もしません。

于 2011-08-21T16:29:45.800 に答える
0

A、B、Cジョブを、Runnableジョブがいつ失敗したかを認識し、制御スレッドについても認識しているaでラップできます。このラッパーは、ジョブが失敗したこと(例外、実行時の条件など)を検出すると、制御スレッドに通知してさらにアクションを実行します。

そうすれば、スレッドをポーリングする必要はありませんが、ラッパーエラー検出器からのシグナルを待つことになります。

于 2011-08-21T16:15:22.780 に答える
0

スレッドが失敗した場合に呼び出されるコールバックをジョブに追加できます。その後、コールバックはすべてのスレッドを停止します。

于 2011-08-21T16:16:48.010 に答える