After Java 1.5 writing multithreaded code become much easier, compared to prior versions. Lots of logic was encapsulated behind classes that were baked inside the JDK. Additionally, the way developers were creating their threads radically changed.
Making use of Executors and ExecutorServices took away the boilerplate code that was needed in order to create and manage the lifecycle of threads.
But in order to make monitoring and debugging easier, threads should have descriptive names. Most of the above executors make use of the DefaultThreadFactory which gives a not so descriptive name (i.e pool-1-thread-1).
Fortunately enough the programmer can pass in its own implementation of a ThreadFactory.
A sample implementation, which gives the thread a descriptive name and a counter can be the following:
The class, along with some unit tests can be found on GitHub.