Я проходил Java-параллелизм на практике и застрял в теме 8.3.1 Создание потока и разрыв . Следующая сноска предупреждает о сохранении corePoolSize
на нуле.
Разработчики иногда испытывают желание установить нулевой размер ядра, чтобы рабочие потоки
в конечном итоге будет снесен и, следовательно, не будет препятствовать выходу JVM, но это может вызвать некоторые
странное поведение в пулах потоков, которые не используют SynchronousQueue для своей рабочей очереди
(как это делает newCachedThreadPool). Если пул уже имеет размер ядра, ThreadPoolExecutor создает
новый поток, только если рабочая очередь заполнена. Таким образом, задачи передаются в пул потоков с рабочей очередью
которая имеет какую-либо емкость и нулевой размер ядра не будет выполняться, пока очередь не заполнится , что обычно
не то, что нужно.
Поэтому, чтобы проверить это, я написал эту программу, которая не работает, как указано выше.
final int corePoolSize = 0;
ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS,
new LinkedBlockingQueue<>());
// If the pool is already at the core size
if (tp.getPoolSize() == corePoolSize) {
ExecutorService ex = tp;
// So tasks submitted to a thread pool with a work queue that has any capacity
// and a core size of zero will not execute until the queue fills up.
// So, this should not execute until queue fills up.
ex.execute(() -> System.out.println("Hello"));
}
выход :
Hello
Итак, предполагает ли поведение программы, что ThreadPoolExecutor
создает хотя бы один поток, если задача отправлена независимо от corePoolSize=0
. Если да, то о чем предупреждение в учебнике.
РЕДАКТИРОВАТЬ: Протестировал код в jdk1.5.0_22 по предложению @ S.K. со следующим изменением:
ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1));//Queue size is set to 1.
Но с этим изменением программа завершает работу без вывода какого-либо вывода.
Значит, я неправильно истолковываю эти утверждения из книги?
РЕДАКТИРОВАТЬ (@sjlee): Трудно добавить код в комментарий, поэтому я добавлю его в качестве правки здесь ... Можете ли вы попробовать эту модификацию и запустить ее как для последних JDK и JDK 1,5?
final int corePoolSize = 0;
ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
// If the pool is already at the core size
if (tp.getPoolSize() == corePoolSize) {
ExecutorService ex = tp;
// So tasks submitted to a thread pool with a work queue that has any capacity
// and a core size of zero will not execute until the queue fills up.
// So, this should not execute until queue fills up.
ex.execute(() -> System.out.println("Hello"));
}
tp.shutdown();
if (tp.awaitTermination(1, TimeUnit.SECONDS)) {
System.out.println("thread pool shut down. exiting.");
} else {
System.out.println("shutdown timed out. exiting.");
}
@ sjlee Опубликовал результат в комментариях.