当池填满时,池中的线程进入阻塞状态

时间:2014-10-19 19:08:50

标签: java multithreading blocking executorservice

我有一个线程池大小为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)

1 个答案:

答案 0 :(得分:0)

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

<强>更新

查看ValueLoaderFactory的第271行以查看线程正在等待的内容。可能你的问题是这样的

  • 任务A将任务B提交给线程池,返回Future,等待未来
  • 任务B将任务C提交给线程池,返回Future,等待未来

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