35

スロットリング/スループット/ペーシングの制限を指定できる Java Executor を探しています。たとえば、1 秒間に処理できるタスクは 100 個までです。さらに多くのタスクが送信された場合、それらはキューに入れられて後で実行されます。これの主な目的は、外部の API またはサーバーにヒットしたときに制限にぶつからないようにすることです。

ベース Java (私がチェックしたので疑わしい) または他の信頼できる場所 (Apache Commons など) のいずれかがこれを提供するのか、それとも自分で作成する必要があるのか​​ 疑問に思っています。軽量なものが望ましいです。自分で書いてもかまいませんが、「標準」バージョンがどこかにある場合は、少なくとも最初にそれを見てみたいと思います。

4

6 に答える 6

8

Java Executor はそのような制限を提供せず、スレッドの量による制限のみを提供しますが、これはあなたが探しているものではありません。

一般に、Executor は、とにかくそのようなアクションを制限するのに間違った場所です。それは、スレッドが外部サーバーを呼び出そうとする瞬間であるべきです。たとえば、スレッドがリクエストを送信する前に待機する制限セマフォを設定することで、これを行うことができます。

呼び出しスレッド:

public void run() {
  // ...
  requestLimiter.acquire();
  connection.send();
  // ...
 }

同時に、(単一の) セカンダリ スレッドをスケジュールして、取得したリソースを定期的に (60 秒ごとに) 解放します。

 public void run() {
  // ...
  requestLimiter.drainPermits();  // make sure not more than max are released by draining the Semaphore empty
  requestLimiter.release(MAX_NUM_REQUESTS);
  // ...
 }
于 2013-11-06T18:42:37.367 に答える
0

個人的には、このシナリオは非常に興味深いと思いました。私の場合、スロットリングの興味深いフェーズは、従来のプロデューサー/コンシューマー同時理論のように消費側であることを強調したいと思います。これは、以前に提案されたいくつかの回答の反対です。つまり、送信スレッドをブロックするのではなく、レート (タスク/秒) ポリシーに基づいて消費スレッドをブロックします。そのため、キューにタスクの準備ができていても、スレッドの実行/消費は、スロットル ポリシーを満たすために待機をブロックする可能性があります。

そうは言っても、良い候補は Executors.newScheduledThreadPool(int corePoolSize) だと思います。この方法では、executor の前に単純なキューが必要になり (単純な LinkedBlockingQueue が適しています)、定期的なタスクをスケジュールして、キューから実際のタスクを選択します (ScheduledExecutorService.scheduleAtFixedRate)。したがって、簡単な解決策ではありませんが、前述のように消費者を抑制しようとすると、十分なパフォーマンスを発揮するはずです。

于 2015-10-15T16:16:02.833 に答える