我正在对现有的 Java 应用程序进行增强。该应用程序是一个消息处理器,每天处理数百万条消息。它基本上是使用 Core Java 编写的,线程和队列是使用 Collection 类实现的。
在此应用程序中,某些类型的消息在单个线程中运行。我的任务是使应用程序的这个特定部分成为多线程以更快地处理消息,因为我们有双处理器。
由于我们使用的是 Java 5,所以我采用了使用 ThreadPoolExcecutor 的方法。我为每个客户端创建了处理器线程,以便可以在其自己的线程中处理特定线程的消息。处理器线程正在实现 Callable 接口,因为这将允许我检查未来对象是否完成前一个任务。
在初始化过程中,我将检查所有客户端并为每个客户端创建处理器线程,并使用它们的 id 作为唯一键将其存储在 map 中。为了跟踪以前提交的作业,我确实使用相同的 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() {
....
....
}
}
问题
上述实现在我的测试环境中运行良好。但是,在生产环境(Edit#1 - Ubuntu、Linux Slackware、Java - 1.6.0_18)中,我们观察到应用程序的其他线程不通过这个新的 ThreadpoolExecutor 管理受到影响。即,他们的任务被延迟了几个小时。是因为 ThreadPoolExecutors 创建的线程正在占用全部资源或其他任何资源,而没有给其他线程机会。
使用 ThreadPoolExceutor 创建的新线程正在执行独立的任务,并且不会与其他线程争用资源。即,没有竞争条件场景。
在日志中,对于新的线程,我可以看到最多有 20 个线程在运行(corepoolsize)并且没有拒绝异常,即提交的数量在队列的范围内。
任何想法为什么会发生这种情况?
提前致谢。