Я использую 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, как я могу узнать количество «живых» потоков (свободных или занятых)?
Заранее спасибо.