Именование потоков и пулов в ExecutorService: решение
Быстрый ответ
Для присваивания имён потокам в ExecutorService используйте пользовательскую ThreadFactory. Вот пример фабрики, которая создаёт потоки с оригинальными именами:
ThreadFactory namedFactory = new ThreadFactory() {
  private final AtomicInteger threadNumber = new AtomicInteger(0);
  public Thread newThread(Runnable r) {
    return new Thread(r, "PoolThread-" + threadNumber.incrementAndGet());
  }
};
ExecutorService executor = Executors.newFixedThreadPool(5, namedFactory);
Таким образом, потоки будут обладать уникальными именами в виде "PoolThread-1", "PoolThread-2" и так далее, что обеспечит удобство их идентификации при выполнении работы.

Использование Guava и Apache
ThreadFactoryBuilder (подарочек от Guava)
Guava предоставляет изящный и простой инструмент – ThreadFactoryBuilder:
ThreadFactory namedFactory = new ThreadFactoryBuilder()
  .setNameFormat("Worker-%d")
  .build();
ExecutorService service = Executors.newFixedThreadPool(10, namedFactory);
Присваивание имен потокам значительно облегчает процесс отладки и мониторинга, превращая поиск ошибок из утомительного занятия в приятный процесс.
BasicThreadFactory из комплекта Apache Commons-Lang
Среди инструментов Apache доступен BasicThreadFactory:
ThreadFactory customThreadFactory = new BasicThreadFactory.Builder()
  .namingPattern("CustomPool-%d")
  .daemon(true)
  .priority(Thread.MAX_PRIORITY)
  .build();
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(customThreadFactory);
Использование Apache позволяет с лёгкостью настроить потоки, управляя такими параметрами как принадлежность к демонам и приоритет.
Kotlin и лямбда-выражения
В Kotlin можно использовать ThreadFactory и лямбда-выражения для определения потоков:
val executor = Executors.newFixedThreadPool(5) { runnable ->
  Thread(runnable).apply {
    name = "KotlinWorker-${someRandomIdGenerator()}"
  }
}
Визуализация
Присваивание имен потокам можно сравнить с процессом присвоения имен солдатам в армии:
Пул потоков: [`Worker1`, `Worker2`, `Worker3`]
Чтобы сделать процесс нагляднее, приведём пример именования потоков:
ExecutorService execService = Executors.newFixedThreadPool(3, new ThreadFactory() {
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    public Thread newThread(Runnable r) {
        return new Thread(r, "WorkerBee-" + threadNumber.getAndIncrement());
    }
});
В логах это будет выглядеть приближенно следующим образом:
[WorkerBee-1] выполняется работа...
[WorkerBee-2] продолжается активная работа...
[WorkerBee-3] "А мы должны работать? Я думал, это время для кофе-паузы."
Такой индивидуальный подход при именовании делает процесс мониторинга активности потоков более простым.
Подробности именования потоков
Присваивание имён для отдельных и запланированных потоков
Даже отдельные потоки могут быть индивидуализированы:
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(
  new ThreadFactoryBuilder().setNameFormat("Worker-%d-on-a-mission").build()
);
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(
  new ThreadFactoryBuilder().setNameFormat("Scheduler-%d-running-against-clock").build()
);
Такого рода настройка помогает легко навигироваться при работе с различными видами исполнителей.
Многоразовые ThreadFactories для поддержания порядка
Создайте повторно используемую ThreadFactory:
public class NamedThreadFactory implements ThreadFactory {
    private final String baseName;
    private final AtomicInteger threadNum = new AtomicInteger(1);
    
    public NamedThreadFactory(String baseName) {
        this.baseName = baseName;
    }
    
    @Override
    public Thread newThread(Runnable r) {
        return new Thread(r, baseName + "-" + threadNum.getAndIncrement());
    }
}
// Пример использования:
ExecutorService pool = Executors.newCachedThreadPool(new NamedThreadFactory("SuperWorkers"));
В каких случаях эффективно использовать индивидуализацию имён потоков?
Практика персонализации имён оказывается эффективной в следующих случаях:
- Идентификации потоков, у которых высокое потребление процессорного времени
 - Решении проблем с дедлоками и утечками памяти
 - Организации работы нескольких пулов в сложных системах
 
Имена потоков должны быть уникальными, информативными и распознаваемыми, следовать общепринятому стандарту именования.
Полезные материалы
- Executors (Java Platform SE 8) — особенно полезные материалы JavaDoc, детально описывающие поведение стандартной фабрики потоков.
 - Lesson: Concurrency (The Java™ Tutorials > Essential Java Classes) — отличный ресурс для глубокого понимания концепций многопоточности в Java.
 - java.util.concurrent (Java Platform SE 7 ) — документация всех инструментов пакета concurrency в Java.
 - [JavaSpecialists 056] – Shutting down Threads Cleanly — статья о том, как правильно завершить работу потоков.
 - ExecutorService (Java Platform SE 8 ) — исчерпывающее руководство по управлению ExecutorService.
 - Java concurrency (multi-threading) – Tutorial — подробный учебник по многопоточности Java от Vogella.
 - Effective Java, 3rd Edition — весомое издание, которое всем рекомендуется к прочтению с целью улучшения навыков в Java.
 


