1. ホーム
  2. java

[解決済み] RejectedExecutionExceptionの原因は何ですか?

2023-05-17 01:17:42

質問

tomcatサーバー(+liferay)でこの例外が発生します。

java.util.concurrent.RejectedExecutionException

私のクラスはこのようなものです。

public class SingleExecutor extends ThreadPoolExecutor {
  public SingleExecutor(){
    super(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
  }

  @Override
  public void execute(Runnable command) {
    if(command instanceof AccessLogInsert){
        AccessLogInsert ali = (AccessLogInsert)command;
        ali.setConn(conn);
        ali.setPs(ps);
    }
    super.execute(command);
  }
}

この行で例外が発生します super.execute(command); このエラーは、キューが満杯のときに発生する可能性がありますが LinkedBlockingQueue のサイズが2^31であり、それほど多くのコマンドが待機していないことが確認されています。

開始時はすべて安定していますが、戦争を再デプロイした後に発生するようになりました。このクラスは戦争の一部ではなく、tomcat/lib の jar に含まれています。

なぜこのようなことが起こるのか、どのように修正すればよいのか、おわかりになりますか。

どのように解決するのですか?

から スレッドプールエクセキュータ JavaDoc (強調)

<ブロッククオート

メソッドで投入された新しいタスク execute(java.lang.Runnable) は拒否されます を実行すると Executor がシャットダウンされた場合 のとき、また Executor が最大スレッド数とワークキュー容量の両方に有限の境界を使い、飽和している場合にも使用されます。どちらの場合でも、execute メソッドは RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) メソッドを呼び出します。 RejectedExecutionHandler . 4つの定義済みハンドラポリシーが提供されています。

  1. デフォルトの ThreadPoolExecutor.AbortPolicy で、ハンドラはランタイム RejectedExecutionException を投げます。
  2. ThreadPoolExecutor.CallerRunsPolicy で、execute を呼び出したスレッド自身がタスクを実行します。これは、新しいタスクが提出される速度を遅くする、簡単なフィードバック制御機構を提供します。
  3. では ThreadPoolExecutor.DiscardPolicy では、実行できないタスクは単にドロップされます。
  4. では ThreadPoolExecutor.DiscardOldestPolicy において、エクゼキュータがシャットダウンされない場合、 ワークキューの先頭にあるタスクはドロップされ、その後実行がリトライされます (これは再び失敗し、これを繰り返す可能性があります)。

他の種類の定義や使用も可能です。 RejectedExecutionHandler クラスを定義して使用することができます。これを行うには、特にポリシーが特定の容量またはキューイングポリシーの下でのみ動作するように設計されている場合、いくつかの注意が必要です。

おそらく、戦争のリロードは Executor . 関連するライブラリを戦争の中に入れてみて、Tomcat の ClassLoader がアプリを正しく再読み込みする可能性が高くなります。