簡體   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