У меня есть веб-служба, которая запускает пул потоков при запуске службы следующим образом:
ExecutorService threadPool = Executors.newFixedThreadPool(30);
threadPool.execute(new WorkerThread());
Класс Workthread выглядит следующим образом:
class WorkerThread implements Runnable {
public WorkerThread () {
}
@Override
public void run() {
String threadName = Thread.currentThread().getName()
}
}
Проблема: иногда имя потока NO_THREAD_YET
, и я не могу понять, при каких обстоятельствах это происходит. Я думаю, что у ExecutorService
просто нет доступных бесплатных угроз, но почему пул не выдает Exception
, когда он полон, и я пытаюсь добавить новый WorkerThread
?
Как я могу убедиться, что Thread.currentThread().getName()
всегда возвращает идентификатор допустимого потока из пула?
Обновлено: класс WorkerThread
- это моя собственная реализация. Это всего лишь сокращенный пример кода, так как другие аргументы я передаю WorkerThread
, например. String
переменные не связаны с этой проблемой.
Это меня смущает, так как рабочий поток не должен запускаться, пока у службы не будет доступного для него потока. минимальный воспроизводимый пример, воспроизводящий это, был бы здесь весьма кстати.
WorkerThread — это пользовательский класс @AlexSalauyou.
DefaultThreadFactory
, используемый для создания потоков в Executors
, создает потоки с именами типа «pool-X-thread-Y», если вы не используете пользовательскую фабрику или не меняете имя вручную. Это должно быть .setName("NO_THREAD_YET")
где-то в вашем коде. Как сказал @HovercraftFullOfEels, Runnable
не будет работать, пока какой-либо поток не станет доступным.
Моя формулировка была неверна, поскольку должно быть так, что «рабочий поток не могу будет работать до тех пор, пока у службы не появится доступный для него поток».
И, вопреки вашему мнению, исполнитель по умолчанию не будет генерировать исключение, если пул занят, просто молча ставит задачу в очередь.
Почему вы удалили этот вопрос?
Скорее всего, причина в том, что вы переименовываете поток вручную где-то в своем коде, например. во время какой-либо другой задачи, которая выполняется в том же пуле потоков:
@Override
public void run() {
// ...
Thread.currentThread().setName("NO_THREAD_YET");
// ...
}
после того, как эта задача завершена, поток «возвращается» в пул, становясь доступным для других задач, и, когда в конечном итоге запрашивается, создается такой вывод.
Чтобы получить неизменяемый идентификатор потока, используйте Thread#getId
Не знаю, почему ОП решил удалить вопрос, поскольку ваш ответ правильный. Я помог отменить удаление. 1+
Хорошо, я узнал, что приложение не переименовывало саму угрозу, как вы сказали, но произошло нечто еще более странное. Имя потока было записано в базу данных с суффиксом "NO_THREAD_YET". Я даже не понял, почему это было реализовано, но я удалил суффикс, и теперь он работает.
из какого класса
WorkerThread
? JDK не содержит таких