[英]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.