我使用ThreadPoolExecutor来管理线程池。我们想要的是:
如果池中的线程数少于corePoolSize,则为新任务启动新线程;
如果池中有多个corePoolSize线程,并且所有线程都处于繁忙状态,请为新任务启动新线程,直到达到maxPoolSize为止。在这种情况下,请拒绝任务;
即使处于空闲状态,也要保持corePoolSize处于活动状态的线程数,如果闲置时间超过keepAliveTime,则多余的线程将死亡
根据Java6文档,keepAliveTime应该如上所述工作。但是在我的测试代码中,它并不一致。
当我将keepAliveTime设置为0时,它可以正常工作,始终使核心线程保持活动状态,并在完成时终止多余的线程。
但是,如下所示,当我将keepAliveTime设置为正值时,它似乎终止了所有空闲线程,无论它们是否是核心线程。
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 500, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>());
assertFalse("Not allow core threads to time out.", executor.allowsCoreThreadTimeOut());
Task task_1 = new Task(1000);
Task task_2 = new Task(1000);
Task task_3 = new Task(1000);
executor.execute(task_1);
executor.execute(task_2);
executor.execute(task_3);
Thread.sleep(1050L);
assertEquals("Completed 3 tasks.", 3, executor.getCompletedTaskCount());
assertEquals("Three threads are in the pool.", 3, executor.getPoolSize());
Thread.sleep(600L);
//////// This assertion will fail: **expected <2> but was <0>**
assertEquals("Two threads are in the pool.", 2, executor.getPoolSize());
////----
private static class Task implements Runnable {
private long sleepMillis;
public Task(final long sleepMillis) {
this.sleepMillis = sleepMillis;
}
public void run() {
try { Thread.sleep(sleepMillis);
} catch (Exception e) { System.out.println(e); }
}
}
关于keepAliveTime或getPoolSize有误解吗?如果getPoolSize不是正确的API,我如何知道“活动”线程(空闲或繁忙)的数量?
提前致谢。
最佳答案
Java 7通过了测试。显然Java 6有一个错误。读取其代码,当队列为空时,所有线程都可以退出,这对于核心线程绝对是错误的。