私は既存のJavaアプリケーションの拡張に取り組んでいます。このアプリケーションは、毎日数百万のメッセージを処理するメッセージプロセッサです。基本的にスレッドとキューを持つCore Javaを使用して記述され、Collectionクラスを使用して実装されます。ThreadPoolExecutorスレッドは他のスレッドと競合しています
このアプリケーションでは、いくつかの種類のメッセージが1つのスレッドで実行されています。私はデュアルプロセッサーを持っているので、アプリケーションのこの特定の部分をマルチスレッドにして、メッセージをより速く処理する作業を与えられました。
Java 5を使用しているので、私はThreadPoolExcecutorを使用してアプローチしました。特定のスレッドのメッセージを独自のスレッドで処理できるように、クライアントごとにプロセッサスレッドを作成しました。プロセッサスレッドはCallableインターフェイスを実装しています。これにより、前のタスクが終了したかどうかを将来のオブジェクトで確認できます。
初期化処理中に、すべてのクライアントを調べ、それぞれのプロセッサスレッドを作成し、そのIDを固有のキーとしてマップに格納します。以前に提出されたジョブを追跡するために、同じIDをユニークキーとして使用して、別のマップに将来のオブジェクトを再度保持します。
以下私が使用したコードの一部抜粋です:メインクラスでは - 上記の実装は私に良い取り組んでいる
ThreadPoolExecutor threadPool = null;
int poolSize = 20;
int maxPoolSize = 50;
long keepAliveTime = 10;
final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(1000);
threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize,keepAliveTime, TimeUnit.SECONDS, queue);
....
....
for (each client...) {
id = getId()..
future = futuremap.get(id);
if(!future.isDone())
continue;
if(future == null || future.isDone()) {
processor = processormap.get(id);
if(processor == null) {
processor = new Processor(.....);
//add to the map
processormap.put(id,processor);
}
//submit the processor
future = threadPool.submit(processor);
futuremap.put(id,future);
}
}
プロセッサスレッド
public class MyProcessor implements Callable<String> {
.....
.....
public String call() {
....
....
}
}
問題
テスト環境。しかし、本番環境(編集#1 -
Ubuntu
、Linux Slackware、Java - 1.6.0_18)では、この新しいThreadpoolExecutorで管理されていない他のスレッドが影響を受けていることがわかりました。すなわち、それらのタスクは何時間も遅延している。これは、ThreadPoolExecutorsによって作成されたスレッドが、すべてのリソースを取得していて、他のスレッドにチャンスを与えていないためですか?
ThreadPoolExceutorを使用して作成された新しいスレッドは独立したタスクを実行しており、リソースの他のスレッドと競合しません。競合状態のシナリオは存在しない。
新しいスレッドについては、最大20スレッド(corepoolsize)が実行され、拒否例外はないことがわかります。つまり、サブミット数がキューの境界内にあります。
これは何が起こっているのですか?
ありがとうございます。
アプリケーション内の任意の場所でスレッド優先度を(プールなどから)変更しますか?これは、異なるプラットフォームに異なる効果をもたらす可能性があります。 – Nr9
いいえスレッドに明示的に優先順位は設定されていません。 – Chandra
あなたはどんなjvmを実行していますか? –