'Understanding ThreadPoolExecutor with ThreadFactory in Java executors framework

Official API docs says:

New threads are created using a ThreadFactory. If not otherwise specified, a Executors.defaultThreadFactory() is used, that creates threads to all be in the same ThreadGroup and with the same NORM_PRIORITY priority and non-daemon status. By supplying a different ThreadFactory, you can alter the thread's name, thread group, priority, daemon status, etc.

An example from here has following lines:

ThreadFactory threadFactory = Executors.defaultThreadFactory();
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2), threadFactory, rejectionHandler);

I am trying to make sense of last sentence of quoted text from the official docs in the context of above code. In other words, how can I pass different ThreadFactory to alter thread's name, thread group, priority and daemon status? How this is supposed to be achieved?



Solution 1:[1]

ThreadFactory is an interface with a single function, Thread newThread(Runnable r). The example implementation in ThreadFactory's Javadoc:

 class SimpleThreadFactory implements ThreadFactory {
   public Thread newThread(Runnable r) {
     return new Thread(r);
   }
 }

Thread has 8 different constructors, allowing you to set thread names, stack sizes, and ThreadGroup. It also has several setters one could call, to control thread priority, class loader, and so forth. One might even return some subclass of Thread with whatever behaviors you choose to give it.

So rather than passing in the return value of Executors.defaultThreadFactory(), you could create your own, and pass an instance of it into your new ThreadPoolExecutor.

Solution 2:[2]

ThreadFactory interface contains newThread(Runnable r) method. You can implement it so created threads will have more meaningful names.

For instance:

  private final static String THREAD_NAME_TEMPLATE = "%s-pool-%d-thread-%d";

  @Override
  public Thread newThread(Runnable r) {
    Thread t = new Thread(group, r,
      String.format(THREAD_NAME_TEMPLATE, namePrefix, poolNumber, threadNumber.getAndIncrement()),
      0);
    t.setDaemon(false);
    t.setPriority(Thread.NORM_PRIORITY);
    return t;
  }

Solution 3:[3]

The easiest solution is to copy and paste the original source code:

private static class DefaultThreadFactory implements ThreadFactory {
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    DefaultThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() :
                              Thread.currentThread().getThreadGroup();
        namePrefix = "pool-" +
                      poolNumber.getAndIncrement() +
                     "-thread-";
    }

    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r,
                              namePrefix + threadNumber.getAndIncrement(),
                              0);
        if (t.isDaemon())
            t.setDaemon(false);
        if (t.getPriority() != Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}

And add the changes you want. Why there's no easier way to do this, I don't know. All I want to do, is change the name of the thread.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mark Storer
Solution 2
Solution 3 tache