Author: Lin Guanhong/The Ghost at my Fingertips

The Denver nuggets: https://juejin.cn/user/1785262612681997

Blog: http://www.cnblogs.com/linguanh/

Making: https://github.com/af913337456/

Sometimes spending a lot of time looking at something that you don’t understand can be a waste of time. Spending time is an investment.

This article is suitable for:

  • Someone who knew about thread pools but was always vague about them
  • Having a close understanding but still wondering about something

Not suitable for:

  • Have not seen completely, suggest you go to see other foundation article first
  • Read, but forget almost, I suggest you review first

This article will reward you for your reading

  • The right reader to make you understand as thoroughly as possibleCommon thread poolsKnowledge related points
  • Unsuitable readers, can have a good concept, child prodigy is another talk

Without further ado, let’s get started. The picture below can be saved and often read. Over time, ingrained

Default constructor

public ThreadPoolExecutor(
    int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler
) 
{... }Copy the code

Absolutely easy to understand constructor parameter explanation

Parameter names role
corePoolSize Maximum number of concurrent threads if the queue is not full
maximumPoolSizes Maximum number of concurrent requests a thread can achieve when the queue is full
keepAliveTime A time limit for how long idle lines can be reclaimed
unit KeepAliveTime Unit of keepAliveTime
workQueue Type of queue that is blocked
RejectedExecutionHandler If maximumPoolSizes + workQueue is exceeded, the task will be assigned to RejectedExecutionHandler

Text description

Relationship between corePoolSize, maximumPoolSize, and workQueue.

  • When the number of threads in the thread pool is less than corePoolSize, the newly submitted task creates a new thread to execute the task, even if there are idle threads in the thread pool.

  • When the number of threads in the thread pool reaches corePoolSize, the new submitted task will be put into the workQueue and wait for the task in the thread pool to execute.

  • When the workQueue is full and maximumPoolSize > corePoolSize, a new thread is created to execute the newly submitted task.

  • If the workQueue is full and the number of submitted tasks exceeds maximumPoolSize, the task is processed by RejectedExecutionHandler.

  • When the number of threads in the thread pool exceeds corePoolSize and the idle time beyond this reaches keepAliveTime, these threads are reclaimed.

  • When allowCoreThreadTimeOut(true) is set, any idle time in the corePoolSize range up to keepAliveTime is also reclaimed.

General flow chart

The flow chart of newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads){
    return new ThreadPoolExecutor(
            nThreads,   // corePoolSize
            nThreads,   // maximumPoolSize == corePoolSize
            0L.// The free time limit is 0
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>() // unbounded blocking queue
        );
}
Copy the code

The flow chart of newCacheThreadPool

public static ExecutorService newCachedThreadPool(a){
    return new ThreadPoolExecutor(
        0.// corePoolSoze == 0
        Integer.MAX_VALUE,  // maximumPoolSize is very large
        60L.// Free is 60 seconds
        TimeUnit.SECONDS,
        // Magical no storage blocking queue, each PUT must wait for a take
        new SynchronousQueue<Runnable>()  
    );
}

Copy the code

The flow chart of newSingleThreadPool

public static ExecutorService newSingleThreadExecutor(a) {
        return 
            new FinalizableDelegatedExecutorService
                (
                    new ThreadPoolExecutor
                        (
                            1.1.0L,
                            TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>(),
                            threadFactory
                        )
                );
    }
Copy the code

Can be seen in addition to more than a FinalizableDelegatedExecutorService agent, its initialization and newFiexdThreadPool nThreads = 1 is the same. The difference is:

  • The ExcutorService returned by newSingleThreadExecutor calls shutdown() at finalize()
  • If we don’t call shutdown() on it, we can be sure to call shutdown() to terminate the thread when it is reclaimed.

With ThreadFactory, you can change the name of a thread, thread group, priority, and daemon state, generally using the default.

Please refer to newFiexdThreadPool for details.

The last

There is also a scheduled task thread pool called ScheduledThreadPool

It is used to handle delayed or timed tasks and is not commonly used

After the