2014-10-19 39 views
0

我有一个具有20的线程池大小的应用程序,并且只要池中的所有线程都耗尽,线程就会永久进入阻塞状态,从而基本上使应用程序变黑。当部分填充池时,应用程序正常工作。线程转储显示线程在运行异步可调用时被阻塞,并且没有关于可调用位置的任何栈信息。我应该看看什么,以便弄清为什么线程在池填满时进入阻塞状态。池中的池在池填满时进入阻塞状态

转储还说没有检测到死锁。 我使用执行程序服务进行线程管理。

Threaddump:

Thread 25903: (state = BLOCKED) 
- sun.misc.Unsafe.park(boolean, long) @bci=0 (Compiled frame; information may be imprecise) 
- java.util.concurrent.locks.LockSupport.park(java.lang.Object) @bci=14, line=186 (Compiled frame) 
- java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await() @bci=42, line=2043 (Compiled frame) 
- java.util.concurrent.LinkedBlockingQueue.take() @bci=29, line=442 (Compiled frame) 
- java.util.concurrent.ThreadPoolExecutor.getTask() @bci=156, line=1068 (Compiled frame) 
- java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=26, line=1130 (Interpreted frame) 
- java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=615 (Interpreted frame) 
- java.lang.Thread.run() @bci=11, line=745 (Interpreted frame) 

Thread 25889: (state = BLOCKED) 
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise) 
- com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run() @bci=34, line=534 (Compiled frame) 

Thread 25888: (state = BLOCKED) 
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise) 
- java.util.TimerThread.mainLoop() @bci=201, line=552 (Compiled frame) 
- java.util.TimerThread.run() @bci=1, line=505 (Interpreted frame) 

Thread 25857: (state = BLOCKED) 
- sun.misc.Unsafe.park(boolean, long) @bci=0 (Compiled frame; information may be imprecise) 
- java.util.concurrent.locks.LockSupport.park(java.lang.Object) @bci=14, line=186 (Compiled frame) 
- java.util.concurrent.FutureTask.awaitDone(boolean, long) @bci=165, line=425 (Compiled frame) 
- java.util.concurrent.FutureTask.get() @bci=13, line=187 (Interpreted frame) 
- dummy1.dummy2.dummy3.ValueLoaderFactory$Builder.build() @bci=16, line=271 (Interpreted frame) 
+0

您是否尝试过使用分析器? Yourkit工作得很好。 – ccleve 2014-10-19 19:43:31

回答

0

ValueLoaderFactory$Builder.build()似乎等待其他线程,因此当前线程无法继续。从本质上讲,这将一个线程从池中移除。如果有多个线程执行此操作,则池会很快变空。

更新

看待ValueLoaderFactory的271线,看看有什么的线程在等待。也许您的问题是这样的

  • 任务A向任务B线程池,得到了Future回来,对未来
  • 任务B等待提交任务C到线程池,得到了Future回来,等待未来

此时,池中有两个线程阻塞,等待其他线程。如果您的线程池大小大于2,则所有内容仍将完成,因为任务C中可用池中有线程。 但是,如果您的线程池大小为2,则此时不会再有任何事情发生。因为任务C在池中没有可用的线程,所以任务B将永久阻塞池中的线程,因为它等待任务C执行,永远不会发生。任务A也是如此,将永远为任务B发生。

+0

有20个线程停留在“ValueLoaderFactory $ Builder.build()”。 – broun 2014-10-19 19:43:45

+0

这是你的问题。 – 2014-10-20 05:21:40

+0

问题是我不知道它在等待什么,基于它们在Future.get()上等待的转储。我不知道为什么只有当整个池耗尽时才永远阻塞,否则线程处理的很好。 – broun 2014-10-20 07:45:26