gpt4 book ai didi

java - ThreadPoolExecutor 线程与其他线程存在争用

转载 作者:行者123 更新时间:2023-12-01 19:25:17 25 4
gpt4 key购买 nike

我正在致力于增强现有的 Java 应用程序。该应用程序是一个消息处理器,每天处理数百万条消息。它基本上是使用 Core Java 编写的,线程和队列是使用 Collection 类实现的。

在此应用程序中,某些类型的消息在单个线程中运行。我的任务是使应用程序的这个特定部分成为多线程,以便更快地处理消息,因为我们有双处理器。

由于我们使用的是 Java 5,所以我采用了使用 ThreadPoolExcecutor 的方法。我为每个客户端创建了处理器线程,以便可以在其自己的线程中处理特定线程的消息。处理器线程正在实现 Callable 接口(interface),因为这将允许我检查 future 对象是否完成前一个任务。

在初始化过程中,我将检查所有客户端并为每个客户端创建处理器线程,并使用它们的 id 作为唯一键将其存储在映射中。为了跟踪以前提交的作业,我再次使用相同的 id 作为唯一键将 future 的对象保留在另一个映射中。

下面是我使用的一些代码片段:在主类中 -

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

有什么想法为什么会发生这种情况吗?

提前致谢。

最佳答案

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

再说一遍,IIRC 在每个工作事件结束时添加 Thread.yield 并没有产生任何积极效果。

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

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

关于java - ThreadPoolExecutor 线程与其他线程存在争用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5507738/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com