NOTE

Create Executor

1. Code to analyze 2. Create the thread factory 3. Create the executor

JavaCreated Updated 1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. Code to Analyze

executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());

2. Create the Thread Factory

  • newDefaultThreadFactory()
protected ThreadFactory newDefaultThreadFactory() {
    // Creates DefaultThreadFactory.
    return new DefaultThreadFactory(getClass());
}

2.1. Set the Thread-Pool and Thread Names

  • DefaultThreadFactory
public DefaultThreadFactory(Class<?> poolType, boolean daemon, int priority) {
    // toPoolName sets the thread-pool name to the class name with a lowercase first letter: nioEventLoopGroup.
    // Continue following the constructor calls downward.
    this(toPoolName(poolType), daemon, priority);
}

public DefaultThreadFactory(String poolName, boolean daemon, int priority) {
    this(poolName, daemon, priority, System.getSecurityManager() == null ?
            Thread.currentThread().getThreadGroup() : System.getSecurityManager().getThreadGroup());
}

public DefaultThreadFactory(String poolName, boolean daemon, int priority, ThreadGroup threadGroup) {
    if (poolName == null) {
        throw new NullPointerException("poolName");
    }
    if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
        throw new IllegalArgumentException(
                "priority: " + priority + " (expected: Thread.MIN_PRIORITY <= priority <= Thread.MAX_PRIORITY)");
    }

    prefix = poolName + '-' + poolId.incrementAndGet() + '-';// name of each thread
    this.daemon = daemon;
    this.priority = priority;
    this.threadGroup = threadGroup;
}
  • The thread-pool name is set to nioEventLoopGroup.
  • Each thread is named nioEventLoopGroup-1-XX.
    • 1 identifies the thread group, while XX identifies the thread within that group.

3. Create the Executor

  • new ThreadPerTaskExecutor(newDefaultThreadFactory())
public final class ThreadPerTaskExecutor implements Executor {
    private final ThreadFactory threadFactory;

    public ThreadPerTaskExecutor(ThreadFactory threadFactory) {
        if (threadFactory == null) {
            throw new NullPointerException("threadFactory");
        }
        this.threadFactory = threadFactory;
    }

    @Override
    public void execute(Runnable command) {
        // When a Runnable is executed, a thread is created through DefaultThreadFactory.newThread.
        threadFactory.newThread(command).start();
    }
}

From the execute method above, we can see that every time a task arrives, the ThreadPerTaskExecutor thread pool creates a new thread to execute it.

3.1. What Kind of Thread Is Created?

  • DefaultThreadFactory.newThread
public Thread newThread(Runnable r) {
    Thread t = newThread(FastThreadLocalRunnable.wrap(r), prefix + nextId.incrementAndGet());
    //...
    return t;
}


protected Thread newThread(Runnable r, String name) {
    // FastThreadLocalThread extends Thread; it is Netty's custom Thread implementation.
    return new FastThreadLocalThread(threadGroup, r, name);
}

The created thread is a FastThreadLocalThread, which extends the JDK’s Thread. Its name is the thread-pool name plus a number.

Discussion

Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub