Sike java thread pool thread series of in-depth analysis - Constructor

ThreadPoolExecutor

(Horizontal screen phone to see the source code is more convenient)


Note: java source code analysis section if no special instructions are based on java8 version.

Brief introduction

ThreadPoolExecutor construction method is to create a thread pool entrance, although relatively simple, but very informative, which can trigger a series of problems, the same way, this is a question often asked in interviews, Tong brother just listed below part of the problem on construction method of ThreadPoolExecutor, if you can answer it, you can not see the analysis below.

problem

(1) ThreadPoolExecutor There are several construction methods?

(2) ThreadPoolExecutor longest construction method has several parameters?

(3) keepAliveTime is what to do with?

(7) The core thread does not time out close? You can overtime closed?

(4) ConcurrentLinkedQueue can not be used as parameters of the task queue?

(5) how the default thread is created?

(6) how to implement your own thread factory?

(7) What are refused strategy?

(8) What is the default strategy of denial?

Construction method

Well, we directly on the code.

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         threadFactory, defaultHandler);
}

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          RejectedExecutionHandler handler) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), handler);
}

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.acc = System.getSecurityManager() == null ?
            null :
            AccessController.getContext();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

ThreadPoolExecutor four constructors, the first three of which are ultimately the last call, which has seven parameters, namely corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler.

corePoolSize

The core number of threads.

When the number of threads that are running less than the core number of threads, a task to create a kernel thread;

When the number of threads that are running equal to or greater than the core number of threads, the first task is not to create a thread but thrown into the task queue.

maximumPoolSize

The maximum number of threads.

When the task queue is full, the paper by the public from the number "Tong brother read the source" original, to a non-core task was to create a thread, but can not exceed the maximum number of threads.

keepAliveTime + unit

Thread remains idle time and units.

By default, this parameter only when two threads are running larger than the core number of threads effective, that is, only for non-core thread.

However, if allowCoreThreadTimeOut been set to true, also effective against the core thread.

That is, when the task queue is empty, the thread remains how long it will be destroyed, mainly by blocking internal queue with timeout poll (timeout, unit) method to achieve.

workQueue

Task queue.

When the number of threads that are running equal to or greater than the core number of threads, the task is to come into the task queue.

This queue must be blocking queue, so it is not like ConcurrentLinkedQueue as an argument, because although it is safe concurrent queue, but it is not a blocking queue.

// ConcurrentLinkedQueue并没有实现BlockingQueue接口
public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
        implements Queue<E>, java.io.Serializable {
    // ...,本文由公从号“彤哥读源码”原创
}

threadFactory

Thread factory.

The default is to use tools in DefaultThreadFactory Executors class that has the disadvantage name of the thread is created automatically generated, can not be customized to distinguish different thread pool, and they are non-daemon threads.

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;
        }
    }

That how a custom thread factory it?

In fact, very simple, own realization of a ThreadFactory, then the name and whether the daemon as a constructor parameter passed in on it.

Interested students can refer to a default thread factory netty in the google or thread factory.

io.netty.util.concurrent.DefaultThreadFactory
com.google.common.util.concurrent.ThreadFactoryBuilder

handler

Rejection policy.

Refused strategy means that when the task queue is full and has reached the maximum number of threads, and this time to add a new task, the thread pool has been unable to bear these new tasks by what logic should be handled.

Commonly used strategies have refused to discard the current task, discard the oldest task, throw an exception, deal with their own caller waiting.

The default strategy is to refuse to throw an exception that can not carry the thread pool, the caller then entered, add the task will throw an exception.

Default deny policy is a relatively simple and crude, but relative to the discard task policy obviously much better, at least the caller that they can catch this exception and then a second treatment.

Egg

OK, ThreadPoolExecutor of this construction method we conducted in-depth analysis today, this, what questions do you have about? Welcome to whisper Tong brother discuss.

Guess you like

Origin blog.51cto.com/14267003/2447781