我有一些java代码可以读取电子邮件收件箱。
启用此服务后,它会生成一个父线程,该线程会持续检查新邮件是否每5秒钟到达一次。它检查,如果没有邮件到达,它会睡5秒钟。如果新邮件已到达,则根据邮件突发情况,它会产生最多10个工作线程来解析这些电子邮件。并且一旦解析了所有邮件,并且没有新邮件到达,工作线程在5秒不活动后被杀死。父线程一直在ping。
有7-8个这样的服务,读取不同的收件箱,继续在我的aws机器上运行,它有一个4核CPU。这些服务占用了我的cpu使用量的350%,我可以通过" top"命令。
我想知道是否有办法可以限制这些线程一直吃CPU资源。这会降低所有其他进程的速度,因为它们不会因为争用而获得CPU使用率。
这是父线程中的代码
@Override
public void run() {
try {
while (!this.isThreadKillRequested()) {
if (this.getMessageCount() > 0) {
WorkerThread worker = getWorkerThread();
if (worker != null && !worker.isAlive()) {
worker.start();
}
} else {
if(this.isAllThreadIdle()){
//ModelUtil.printOutput("all idle. nothing to do");
}
}
Thread.sleep(MESSAGE_PROCESSOR_SLEEP_TIME);
}
} catch (InterruptedException e) {
ErrorLogger.logError("InterruptedException exception in monitoring thread",
GlobalConfig.msgException + e.getMessage());
e.printStackTrace();
}
}
private WorkerThread getWorkerThread() {
WorkerThread worker = null;
for (Map.Entry<String, ThreadPerformance> entry : this.threadPool.entrySet()) {
ThreadPerformance p = entry.getValue();
if (p.isThreadIdle()) {
worker = p.getThisThread();
break;
}
}
if (worker == null && this.threadPool.size() < MAX_POOL_SIZE) {
double overallThroughput = 0.00;
//some logic to calculate throughput
if (overallThroughput < MIN_THROUGHPUT) {
worker = new WorkerThread(this, this.getUniqueThreadId());
//add in pool
}
System.out.println("Overall Throughput - " + overallThroughput);
System.out.println("Pool Size - " + this.threadPool.size());
}
return worker;
}
答案 0 :(得分:1)
通过减慢刷新周期和缩短线程来限制线程CPU消耗是最容易的。每20秒尝试一次,并将工作线程数限制为4.除非需要所有线程和快速刷新率,否则会对CPU造成不必要的压力。特别是在检查8个邮箱时。
所有邮箱同时收到大量新邮件的概率很低。因此,可以保持总线程数,并且可以基于每个邮箱的新项目的百分比来分配每个邮箱的线程数。这将增加最需要它的邮箱的吞吐量,同时将线程数限制为可管理的数量。