我有一个线程池大小为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 :(得分:0)
ValueLoaderFactory$Builder.build()
似乎在等待其他线程,因此当前线程无法继续。从本质上讲,这会将一个线程从池中移除。如果多个线程执行此操作,则池很快就会变空。
<强>更新强>
查看ValueLoaderFactory的第271行以查看线程正在等待的内容。可能你的问题是这样的
Future
,等待未来Future
,等待未来此时,池中有两个线程被阻塞,等待其他线程。如果您的线程池大小大于2,则所有内容仍将完成,因为池中有一个线程可用于任务C. 但是,如果线程池大小为2,那么此时不会再发生任何事情。因为任务C的池中没有可用的线程。因此,任务B永远会阻塞池中的线程,因为它等待任务C执行,这将永远不会发生。任务A也是如此,任务B将永远发生。