我正在使用
FixedThreadPool
创建 Java 线程池,池大小为 10。
从构造函数来看,是
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
这意味着我创建了一个核心线程池大小为 10 且最大线程池大小为 10 的线程池。根据 Java 8 官方文档,这意味着:
然而,在检查计数器时,我对以下计数器感到困惑:
ActiveCount
= 0PoolSize
= 10QueueSize
= 1上面的计数器出现了很多次,所以这不仅仅是一次性的情况。我还看到一些这样的计数器:
ActiveCount
= 1PoolSize
= 10QueueSize
= 1在这种情况下,请求仍在队列中,而正在积极处理任务的线程少于池大小。有谁知道为什么会发生这种情况?我在这里错过了什么吗?
我不知道这是否是一个“好”答案,但我会添加它,因为看起来有点不明显。
当我用一个非常短的测试用例(任务)测试OP的代码时,我得到了与OP类似的结果。这可以被认为是微基准的常见问题。或者也可能是生产代码设计不当造成的问题。例如:
public static void main( String[] args ) {
ExecutorService es = Executors.newFixedThreadPool( 10 );
System.out.println( es );
for( int i = 0; i < 20; i++ )
es.execute( () -> {System.out.println( "test" ); } );
// es.execute( FixedThreadPool::test );
System.out.println( es );
es.shutdown();
}
产生如下输出:
test
test
test
java.util.concurrent.ThreadPoolExecutor@7506e922[Running, pool size = 10, active threads = 2, queued tasks = 10, completed tasks = 8]
test
test
test (more "test" lines removed)
另一方面,如果我向测试任务添加更长的延迟,例如 2 秒的睡眠延迟,则执行器中的所有 10 个线程都显示为活动状态。
public class FixedThreadPool {
public static void main( String[] args ) {
ExecutorService es = Executors.newFixedThreadPool( 10 );
System.out.println( es );
for( int i = 0; i < 20; i++ )
es.execute( FixedThreadPool::test );
System.out.println( es );
es.shutdown();
}
private static void test() {
try {
System.out.println( "test" );
Thread.sleep( 2000 );
} catch( InterruptedException ex ) {
// exit
}
}
}
输出:
test
test
java.util.concurrent.ThreadPoolExecutor@7506e922[Running, pool size = 10, active threads = 10, queued tasks = 10, completed tasks = 0]
test
test
test (more "test" lines trimmed)