Four kinds of parsing thread pool

First we look at the code to obtain four kinds of thread pool:

    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);
    ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();

复制代码

Can be found in the four thread pools are generated by the Executors class. Sequentially opening the four internal implementation method of discovery, all the same the ThreadPoolExecutor () constructor their final call, but the difference lies in the different parameters of the constructor. We look at the list of parameters ThreadPoolExecutor of:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
复制代码

It is because of these different parameters lead to different working mechanism of four kinds of thread pool. Reference source for the comment parameters, we list the meaning of the parameters.

  • corePoolSize: a core number of threads in the thread pool thread resident, even if they are idle, it will not be destroyed, unless the value of the set allowCoreThreadTimeOut.
  • maximumPoolSize: The maximum number of threads in the thread pool
  • keepAliveTime: more than the number of cores of additional threads in which non-core thread, destroyed after the specified maximum idle time. (Assumed time 5s, core threads 2, the current thread is 4, the number of threads than the remaining two core threads will be destroyed after being idle for 5 seconds.)
  • unit: unit of time
  • workQueue: waiting queue
  • threadFactory: generation thread factory
  • handler: When the queue is full capacity and the number of thread pool reaches the maximum, how to deal with new tasks.
    • AbortPolicy (default): Direct throws an exception
    • CallerRunsPolicy: the caller's location to the thread. (Assuming that the current caller thread is the Main, then on to Main processing)
    • DiscardOldestPolicy: discard processing task for the longest time, and then execute the current task. (Least recently processed in the queue node is actually the head of the queue to view the source code is indeed calling poll () method)
    • DiscardPolicy: lose the job, and does not throw an exception.

Thread pool mechanism:

When the thread pool continued to add tasks,
the current number of threads when the thread is less than the number of cores, the new thread.
The current number of threads reaches the number of kernel threads when the task into the waiting queue.
When the queue is full, continue to create new threads.
When the pool reaches the maximum number of threads and also waiting queue is full, take a denial of service policy.

Next we have to analyze different thread pool based on the parameters:

FixedThreadPool

 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
复制代码

We can see corePoolSize core number of threads and the maximum number of threads maximumPoolSize is consistent, and keepAliveTime zero. workQueue is LinkedBlockingQueue, this is a chain blocking queue. It can be concluded: the thread pool is a fixed number of thread pool, and there is a waiting queue unbounded. We can deduce the scene of the thread pool for steady amount of processing tasks. For example the average received one second task 10, task received an amount of curve is not steep.

Suitable scene: big task for a small number of (large-tasking slow, if the number of threads of many things, but the loss when switching thread context, so in a certain number of threads of control).

CachedThreadPool

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
复制代码

We can see corePoolSize core thread pool, it indicates that there is no core thread pool thread, the thread means that can be recovered are destroyed, sometimes the thread pool will be empty. And maximumPoolSize int is the maximum, equivalent to the representatives of the thread pool can create unlimited threads. keepAliveTime 60, on behalf of idle 60 seconds recovery thread. workQueue is SynchronousQueue, the synchronization queue is not a queue capacity, that is, after the arrival of a task, to wait for a thread to spend, then continue to add tasks. We derive the thread pool for processing usually no assignments, but sometimes instant surge of assignments scene.

Suitable scene: a large number of small tasks (each task processing quickly, without frequent when threading half, switch to another thread).

ScheduledThreadPool

public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }
复制代码

We can see that the biggest difference is that the thread pool parameters workQueue is DelayedWorkQueue. The queue is a time delay by small to large stacks. And when the delay time is less than the queue 0 of the head node returns the node. So the thread pool may specify a time for regular tasks. It can also be incremental delay time when adding a task to perform periodic tasks.

Suitable scenario: a timing cycle task or tasks.

SingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
复制代码

We can see that the core number of threads and the maximum number of threads maximumPoolSize corePoolSize the thread pool is 1, on behalf of the thread has one and only one fixed thread, since it is single-threaded, so the thread pool implementation is serial operation, no concurrency effect. workQueue is LinkedBlockingQueue, this is a chain blocking queue. So the thread pool for tasks serial execution queue.

Suitable scenarios: sequential serial tasking.

Readers may wonder keepAliveTime is 0 meaning represented? It is immediately recycled thread or never recover it?

keepAliveTime parameter annotation clearly indicate only useful for non-core thread. We can speculate from ScheduledThreadPool source, if the representative is 0 never recovered, then ScheduledThreadPool once created out of non-core thread would not have recovered? This is very unreasonable. So I believe that 0 for immediate recovery.

public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }
复制代码

The author is limited, if error correction urge comment.

Transfer from my personal blog vc2x.com

Guess you like

Origin juejin.im/post/5d7fb686e51d453bb13b66d7