2012-12-13 63 views
0

我有,我使用Java執行執行一些可運行的tomcat的web應用。如何「殺死」從一個執行線程?

首先我從我的遺囑執行人實例分配執行服務是這樣的:

executorService = Executors.newFixedThreadPool(nThreads, new MyThreadFactory(threadFactoryName)) 

然後,我用執行人服務發射任務:

executorService.execute(new MyRunnable); 

然後,它似乎工作。但我的問題是,我在追逐某種泄漏的,我一個在運行的服務器後出現此錯誤:

Caused by: java.lang.OutOfMemoryError: unable to create new native thread 
at java.lang.Thread.start0(Native Method) 
at java.lang.Thread.start(Thread.java:640) 
at java.util.concurrent.ThreadPoolExecutor.addIfUnderCorePoolSize(ThreadPoolExecutor.java:703) 
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:652) 
at something.server.ThreadExecutor.execute(MyRunnable.java:91) 

我使用的Java VisualVM的上Tomcat實例跟蹤的線程分配。我看到,當我調用'newFixedThreadPool'時,我看到'nThreads'的新線程。但是他們的工作完成後,我發現線程的狀態處於「等待」狀態。

這是正常的嗎?我不相信它,我知道runnables完成他們的工作,但執行者服務從未釋放線程。我能做些什麼來解救他們,還是我完全超出了範圍?

+0

不知道,我明白你的意思,但一個池真的意味着池中的對象(這裏是線程)被重用。所以這很正常......對於OOM:你是否使用ThreadLocals? –

+0

我認爲有關* fixed * ThreadPool的所有內容都是它始終具有相同數量的線程?在你的ThreadFactory中,你可以給線程一個特定的名字,然後配置文件,如果它是來自該執行器的線程正在瘋狂?我想他們不是,這是一些其他的泄漏。 – Fildor

+0

你在32位或64位操作系統上運行? – jtahlborn

回答

4

我想你正在爲每個請求實例化一個新的ExecutorService,或類似的東西。

在完成提交任務後,您應該只實例化一個ExecutorService,並重新使用它,或者在服務上調用shutdown()。該shutdown功能將等待任務完成,然後釋放線程。

2

是正常嗎?我不相信它,我知道runnables完成他們的工作,但執行者服務從未釋放線程。

是的,這是正常的。事實上,這種行爲是可取的,因爲創建一個新線程是一個昂貴的操作。在執行程序關閉之前,池線程(或者至少'core'線程池)將繼續存在。

我能做些什麼來釋放他們,還是我完全超出了範圍?

你應該能夠配置你的線程池有一個更小的'核心'線程池和/或更小的keepAlive時間。有關詳細信息,請參閱javadoc


[M]ÿ問題是,我在追逐某種泄漏的,我一個在運行的服務器後出現此錯誤:

這OOME不一定的指示泄漏。這可能是因爲你還沒有爲您要創建的線程數量留下了足夠的非堆內存的標誌。 (換句話說,你的線程池太大了。)

1

你正在實例化一個固定的線程池。 ExecutorService不會釋放線程,直到您通過調用ExecutorService.shutdown()ExecutorService.shutdownNow()終止ExecutorService本身。