繁体   English   中英

部署到tomcat时,长时间运行的多线程应用程序运行速度比从命令行运行时慢4倍

[英]Long running multi threaded application runs 4x slower when deployed to tomcat than when run from command line

当我从命令行运行这个长时间运行的进程时,它需要大约30秒才能完成。 当我将相同的代码部署到tomcat7并从一个简单的Vaadin Web应用程序调用相同的函数时,它需要将近150秒。 这是特定功能执行的时间,而不是与接口相关的任何事情。

这是一个说明问题的简单示例:

public static void main(String[] args) {

    try {
        multiCounter(800);
    } catch (InterruptedException | ExecutionException e) {e.printStackTrace();}

    System.out.println("Completed");
}


public static void multiCounter(int numberOfCounters) throws InterruptedException, ExecutionException
{   

    //estimate the number of available processors
    int maxNumberOfThreads = Runtime.getRuntime().availableProcessors();

    //create thread pool and queue for future jobs
    ExecutorService pool = Executors.newFixedThreadPool(maxNumberOfThreads);

    ArrayList<Future<Integer>> futureJobs = new ArrayList<Future <Integer>>();

    for(int index=0; index<numberOfCounters; index++)       
    {
        Callable<Integer> callable = new dummyCalculator();
        Future<Integer> future = pool.submit(callable);
        futureJobs.add(future);
    }

    //placeholder for results
    ArrayList <Integer> results= new ArrayList <Integer>(0);

    //pull completed jobs from queue and extract results,
    //adding to results container
    for(Future<Integer> future : futureJobs) 
    {results.add(future.get());}

    for(Integer res : results)
    {System.out.println("Count:" + res);}

    //close thread pool
    pool.shutdown();
}

final static class dummyCalculator implements Callable<Integer>
{   
    @Override
    public Integer call() throws Exception {

        Integer counter = 0;

        for(int p1Index=0; p1Index<800; p1Index++)
        {   
            for(int p2Index=p1Index; p2Index<800; p2Index++)
            {
                for(int markerIndex=0; markerIndex<200; markerIndex++)
                {counter++;}
            }
        }

        return(counter);
    }
}

我运行它的服务器有48个可用内核。 当我从命令行运行此代码时,我得到48个线程,每个线程运行~98%。 当我通过tomcat运行它时,根据顶部,每个线程最高可达82-86%。 如果我减少tomcat上代码中的线程数,则每个线程的%增加。 12个线程将获得每个线程92%。 1个线程99%......

tomcat是否会以某种方式限制这个步骤池,或者有一些我不知道的线程的额外开销? 或者在这种情况下有更好的多线程方法吗? 一些开销显然是可以接受的,但似乎没有什么东西可以让它通过tomcat花更长的时间。

您是否尝试确保Tomcat和您的作业使用的线程总数总计为系统中的核心数? 我冒昧地说,你可能会接近这些线程的99%执行。

我遇到的另一个问题是Tomcat线程的优先级是否高于工作线程。 如果是这种情况,那么你应该在一致的基础上看到这种差异。 我不记得你是否可以使用jconsole或visualvm看到线程优先级,但是可能增加线程池的线程优先级应该提供更多的cpu周期,但这会影响tomcat处理Web请求的能力。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM