简体   繁体   English

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

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

When I run this long running process from the command line it takes about 30 seconds to complete. 当我从命令行运行这个长时间运行的进程时,它需要大约30秒才能完成。 When I deploy this same code to tomcat7 and call the same function from a simple Vaadin web application it takes almost 150 seconds. 当我将相同的代码部署到tomcat7并从一个简单的Vaadin Web应用程序调用相同的函数时,它需要将近150秒。 This is the time for a specific function to execute, not anything related to interface slowing it down. 这是特定功能执行的时间,而不是与接口相关的任何事情。

Here's is a simple example that illustrates the problem: 这是一个说明问题的简单示例:

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);
    }
}

The server I'm running this on has 48 available cores. 我运行它的服务器有48个可用内核。 When I run this code from the command line I get 48 threads running ~98% each. 当我从命令行运行此代码时,我得到48个线程,每个线程运行~98%。 When I run it through tomcat each thread tops out at around 82-86% according to top. 当我通过tomcat运行它时,根据顶部,每个线程最高可达82-86%。 If I decrease the number of threads in the code on tomcat, the % per thread increases. 如果我减少tomcat上代码中的线程数,则每个线程的%增加。 12 threads will get me 92% per thread. 12个线程将获得每个线程92%。 1 thread 99%... 1个线程99%......

Does tomcat do something to limit this tread pool in some way, or have some additional overhead with threads that I am not aware of? tomcat是否会以某种方式限制这个步骤池,或者有一些我不知道的线程的额外开销? Or is there a better way to multi-thread in this case? 或者在这种情况下有更好的多线程方法吗? Some overhead is obviously acceptable, but something doesn't seem right here for it to take that much longer through tomcat. 一些开销显然是可以接受的,但似乎没有什么东西可以让它通过tomcat花更长的时间。

Have you tried to ensure that the total number of threads that Tomcat and your jobs use totals the number of cores on your system? 您是否尝试确保Tomcat和您的作业使用的线程总数总计为系统中的核心数? I would venture to say that you would probably get closer to the 99% execution for those threads. 我冒昧地说,你可能会接近这些线程的99%执行。

The other question that I have is if the Tomcat threads have a higher priority than your worker threads. 我遇到的另一个问题是Tomcat线程的优先级是否高于工作线程。 If that is the case then you should be seeing this difference on a consistent basis. 如果是这种情况,那么你应该在一致的基础上看到这种差异。 I do not recall if you can see the thread priority using jconsole or visualvm but maybe increasing the thread priority of the thread pool should provide more cpu cycle but that will affect tomcat ability to handle web requests. 我不记得你是否可以使用jconsole或visualvm看到线程优先级,但是可能增加线程池的线程优先级应该提供更多的cpu周期,但这会影响tomcat处理Web请求的能力。

暂无
暂无

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

相关问题 多线程程序运行速度比单线程慢 - Multi-Threaded program runs slower than single threaded 从Eclipse构建时,为什么Java程序比从命令行构建时慢? - When built from eclipse, why is a java program slower than when built from command line? 服务器上的多线程应用程序比单线程慢(与JUnit测试不同) - Multi threaded application on server slower than single threaded (unlike in JUnit tests) 出乎意料的 VarHandle 性能(比替代方案慢 4 倍) - Unexpected VarHandle performance (4X slower than alternatives) 多线程ByteBuffers比顺序慢? - Multi-threaded ByteBuffers slower than sequential? Apache 公共命令行执行方法在 tomcat 应用程序中运行并抛出 ExecuteException 时返回退出代码 -1 - Apache commons command line execute method is returning exit code -1 when running in tomcat application and throwing ExecuteException Apache tomcat 7在localhost上运行良好,但是部署的war文件在尝试运行时抛出异常 - Apache tomcat 7 runs well on localhost but deployed war files throw exceptions when try to run 从命令行运行应用程序时,JavaFX 8视频播放冻结 - JavaFX 8 video playback freeze when running application from command line 从Netbeans部署时无法启动Tomcat应用程序 - Tomcat application cannot be started when deployed from Netbeans 在命令行上运行时出现ClassNotFoundException,但在IntelliJ IDEA上运行良好 - ClassNotFoundException when running on command line but runs fine on IntelliJ IDEA
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM