preface
Coding with a single thread in mind during daily development, without regard for performance in a multithreaded state. The result is too many requests for the application to respond to. In order to solve the problem of too many requests, the concept of thread pool was derived. Through the “pool” idea, thus reasonable processing requests. This article has documented the use of thread pools in Java and how they work. You are welcome to correct any errors.
What is a thread pool?
Thread pool is a software design pattern for concurrent execution of computer programs. The thread pool maintains multiple threads waiting for tasks to be assigned by the scheduler to execute concurrently, which improves performance and avoids execution delays caused by the frequent creation and destruction of threads for short-term tasks.
What problem does the thread pool solve?
When we talk about thread pool, we must start with the life cycle of the thread.
](/img/bVcSinY)
As you can see from the diagram, no matter how long the task is executed, each thread goes through a state from birth to death. The purpose of using a thread pool is to avoid duplicate creation of the thread and thus save time Running to the Terminated thread. At the same time, the thread will be reused to minimize the savings of system resources and improve the response speed at the same time.
Use of thread pools
Thread pool creation
Use ThreadPoolExecutor with 7 parameters to complete the creation of the thread pool
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
- CorePoolSize: The maximum value of the core thread in the thread pool
- MaximumPoolSize: The maximum number of threads in the thread pool
- KeepAliveTime: The amount of time that a non-core thread lives when it is idle
- Unit: KeepAliveTime A unit used in seconds, minutes, hours, etc
- WorkQueue: The blocking queue type
- ThreadFactory: A threadFactory used to configure the name of the thread, whether it is a daemon thread, etc
- Handler: The rejection policy for the thread pool
Common blocking queue
ArrayBlockingQueue
Bounded blocking queue of the underlying array-based implementation
LinkedBlockingQueue
The underlying blocking queue is based on a single linked list. The capacity can be configured. The default capacity without configuration is Integer.MAX_VALUE
Thread factory
inAlibaba Java Development ManualIs mandatory to specify the name of the thread
](/img/bVcSinX)
Since hutool is used a lot for work, it also includes a wrapper around ThreadFactory, which can be conveniently named
ThreadFactory threadFactory = ThreadFactoryBuilder.create().setNamePrefix("myThread-").build();
Rejection policies
When the number of worker threads in the thread pool is greater than MaximumPoolSize, the thread will no longer accept the task and execute the corresponding rejection policy. There are currently four supported rejection policies:
- AbortPolicy (default) : Discards the task and throws it
RejectedExecutionException
abnormal - CallerRunsPolicy: Handled by the caller
- Discarded top task in queue and re-queued
- DiscardPolicy: Discards the task without throwing an exception
The execution logic of the thread pool
/ / create a thread factory ThreadFactory ThreadFactory = ThreadFactoryBuilder. The create () setNamePrefix (" myThread - "). The build (); ThreadPoolExecutor = new threadPoolExecutor (5, 10, 10, TimeUnit.seconds); new ArrayBlockingQueue<>(100), threadFactory, new ThreadPoolExecutor.AbortPolicy());
The execute () method
// Combine value; Private Final AtomicInteger CTL = new AtomicInteger(CTLOF (RUNNING, 0));
Public void execute(Runnable command) {if (command == null) throw new NullPointerException(); Int c = ctl.get(); If (workerCountOf(c) < corePoolSize) {if (addWorker(command, true)) return; c = ctl.get(); } // If (IsRunning (c) && WorkQueue. Offer (command)) {// Recheck thread pool status int recheck = ctl.get(); // If the thread pool is not Running, remove the added task and execute the rejection policy if (! isRunning(recheck) && remove(command)) reject(command); Else if (WorkerCountOf (reCheck) == 0) addWorker(null, false); } // Failed to add task, reject policy else if (! addWorker(command, false)) reject(command); } // addWorker() completes the creation of the thread
Execute the process
Common thread pool
newCachedThreadPool
Public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.max_value, 60L); TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } // 6 parameters, Public static ExecutorService newCachedThreadPool(ThreadFactory ThreadFactory) {return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), threadFactory); }
The maximum number of threads allowed to be created is INTEGER.MAX_VALUE, which may create a large number of requests, resulting in OOM
newFixedThreadPool
// The number of core threads is equal to the maximum number of threads, Public static ExecutorService newFixedThreadPool(int nThreads) {return new using a linked list-based blocking queue with no capacity configured ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); Public static ExecutorService newFixedThreadPool(int nThreads, int nThreads) ThreadFactory threadFactory) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory); }
The maximum allowable length of the request queue is INTEGER.MAX_VALUE, which may pile up so many requests that an OOM may result
newSingleThreadExecutor
// The core thread and the maximum number of threads are both 1, Use a blocking queue based on linked list public static ExecutorService newSingleThreadExecutor () {return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
Thread pool with only one thread, receiving tasks is equivalent to serial execution
newScheduledThreadPool
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
A pool of threads that can execute periodically
References:
- Java thread pool parsing (juejin.cn)
- Stop saying you don’t understand thread pools — be an elegant Siege Lion (juejin.cn)
- Java Thread Pool Implementation Principles and Practice in Meituan Business – Meituan Technical Team (meituan.com)
Read the original