8

私はこの問題を抱えています、私は持っています

private ScheduledExecutorService executor =  
     Executors.newSingleThreadScheduledExecutor(); 

および 50 ミリ秒ごとに作成されるタスク:

executor.scheduleAtFixedRate(myTask, 0, 50, TimeUnit.MILLISECONDS);

myTask完了するまでに時間がかかる場合があります (2 ~ 3 秒程度) が、newSingleThreadScheduledExecutor は、次にスケジュールされた myTask が現在のタスクが完了するまで待機することを保証します。

ただし、時々このエラーが発生します。

実行する:java.util.concurrent.RejectedExecutionException

私は何をすべきか?ありがとう

4

3 に答える 3

15

エグゼキューターが何をしているかを考えてみましょう。指示に従って、50 ミリ秒ごとに 1 つのタスクを実行しています。このタスクの実行に 50 ミリ秒もかからないと仮定すると、すべて問題ありません。ただし、実行に 2 ~ 3 秒かかることがよくあります。これが発生すると、エグゼキュータは引き続き 50 ミリ秒ごとに実行を試みますが、スレッドが 1 つしかないため実行できず、長時間実行タスクがまだ進行している間にトリガーされた実行を拒否します。これにより、表示される例外が発生します。

これを修正するには、2 つの選択肢があります (単一のスレッドに固執する場合)。

  1. scheduleWithFixedDelayではなく使用しscheduleAtFixedRateます。javadoc を注意深く読むと、1 つのタスクが終了してから次のタスクが開始されるまでに 50 ミリ秒待機することがわかります。そのscheduleWithFixedDelayため、そのうちの 1 つに長い時間がかかっても「オーバーラップ」することはありません。対照的に、scheduleAtFixedRate各実行にかかる時間に関係なく、50 ミリ秒ごとに実行しようとします。

  2. エグゼキュータが実行の失敗を処理する方法を変更します。デフォルトでは例外をログに記録しますが、たとえば無視するように指示することもできます。java.util.concurrent.RejectedExecutionHandlerたとえば、 of のサブクラスを見てみましょうDiscardPolicy。これは、実行できないタスクを黙って削除するだけです。これらは、ファクトリ クラスScheduledThreadPoolExecutorを使用するのではなく、ハンドラーを直接構築してコンストラクターに渡すことで使用できます。Executors

オプション(1)があなたが望むものだと思います。

于 2009-12-21T08:31:42.330 に答える
4

この例外は、次のいずれかの場合にスローされます。

  1. エグゼキュータをシャットダウンしました
  2. エグゼキュータのワークキューまたは最大スレッドの範囲を超えました。

私は後者が起こっていると思います。タスクを実行して時間がかかると、プールに十分なスレッドがないため、後続のスケジュールされたタスクを実行できません。

また:

  1. より大きなプールサイズを使用するか、cachedThreadPoolを使用してください
  2. 拒否ポリシーを変更して、たとえばThreadPoolExecutor.CallerRunsPolicyを使用します。
  3. 長時間実行タスクを実行するための別のエグゼキュータを作成し、スケジュールされたタスクからこれらを実行します。実際には、プールサイズを増やすことを条件に、同じExecutorインスタンスを使用してこれを行うことができます。

ThreadPoolExecutorjavadocも参照してください。

于 2009-12-21T04:19:39.347 に答える
-1

Java 7 では、どちらも最初の実行の準備が整うまで待機してから、次の実行を開始します!

ここをチェックしてください:
http://download.java.net/jdk7/archive/b123/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

またはここ:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

于 2014-06-05T11:09:43.903 に答える