3

我正在对现有的 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)并且没有拒绝异常,即提交的数量在队列的范围内。

任何想法为什么会发生这种情况?

提前致谢。

4

1 回答 1

0

我之前在 Linux 线程方面的经验清楚地表明,与在相同负载下运行在 Windows 中的相同系统相比,它在非常繁忙时更容易出现线程饥饿。我编写了一个测试程序,表明在 CPU 负载较重的情况下,当使用标准等待/通知原语 - IIRC 时,一些线程将获得比其他线程更多的 CPU 时间,数量级。我的解决方案是在公平模式下使用可重入锁来循环它们。

同样,IIRC 在Thread.yield每个工作事件结束时加入并没有积极影响。

所有这些都可能会受到您的 Linux 发行版使用的几个线程库中的哪一个的显着影响。

您可以通过向主导工作负载的工作队列添加一个节流器来获得一些改进,尽管最好能以某种方式适应其他不相关线程上待处理的工作量。

于 2011-04-01T06:55:08.343 回答