Java多线程占用了所有的CPU资源

时间:2018-03-29 23:13:52

标签: java multithreading

我有一些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;
        }

1 个答案:

答案 0 :(得分:1)

通过减慢刷新周期和缩短线程来限制线程CPU消耗是最容易的。每20秒尝试一次,并将工作线程数限制为4.除非需要所有线程和快速刷新率,否则会对CPU造成不必要的压力。特别是在检查8个邮箱时。

所有邮箱同时收到大量新邮件的概率很低。因此,可以保持总线程数,并且可以基于每个邮箱的新项目的百分比来分配每个邮箱的线程数。这将增加最需要它的邮箱的吞吐量,同时将线程数限制为可管理的数量。