2

彼ら。私はマルチスレッドにまったく慣れていないので、頭を包み込むことができないタスクがあります。次のセマンティクスを維持するクラスを書きたい:

interface TokenAwareTaskExecutor(){
   //Callable<Long> returns the time the task finishes.
   public void submitTask(String token, Callable<Long> task);
   public long getDelay();
}

タスクを送信すると、サービスは、そのようなトークンが以前の呼び出しによって追加されているかどうかを調べます。そうである場合、遅延の後、同じトークンを持つ他の送信済みタスクが実行された後に、タスクを送信する必要があります。そのようなトークンが存在しない場合は、トークンを追加して、遅滞なくタスクを送信してください。全体として、特定の頻度で一意のトークンを個別に処理できる負荷分散戦略を実装したいと考えています。何を見るべきか教えてください。

4

2 に答える 2

0

異なるトークンが多すぎない場合、1 つの解決策は、各トークンを のインスタンスにマップすることですScheduledThreadPoolExecutor。次に、エグゼキューターがマップで見つかった場合は、遅延を使用してタスクをスケジュールします。それ以外の場合は、新しい実行プログラムを作成し、遅滞なくスケジュールします。

もう 1 つの方法は、トークンを 1 つだけ使用し、そのトークンの待機中のタスクの数と、そのトークンを使用する最後のタスクのスケジューリング時間をカウントするアトミック カウンターで構成されるオブジェクトScheduledThreadPoolExecutorにトークンをマップすることです。ScheduleInfoカウンターと時間への変更は、タンデムで発生し、同期する必要があります。

synchronizedのメソッドenter()を使用して、スケジューリング時にカウンターをインクリメントする外側の Callable で、各受信タスクをラップしますScheduleInfo。カウンターがゼロの場合は、遅滞なくスケジュールを設定し、スケジュール時刻を現在の時刻に設定します。カウンターが 0 より大きい場合は、スケジュール時間に遅延を追加し、その正確な時間にスケジュールします。

内側のタスクが終了すると、外側のタスクは再びカウンターをデクリメントする必要があります。これは の別のsynchronizedメソッドexit()で行われScheduleInfoます。遅延を解釈する方法がわかりません (呼び出し間の時間、または1 つのタスクの終了と次の開始の間の時間)。後者の場合、ここでもスケジュール時間を調整する必要があります。繰り返しますが、enterexitが重ならないことが重要であるため、同期する必要があります。

これは、コードを試していない私の頭から離れているため、批判を歓迎します。

于 2013-04-06T15:05:28.537 に答える