Thread pool status:
ThreadPoolExecutor uses the high 3 bits of int to represent the thread pool status, and the low 29 bits represent the number of threads.
This information is stored in an atomic variable ctl.
When the task volume is large, an emergency thread will be created to execute the task, and it will be destroyed after execution.
Number of core threads == Maximum number of threads (no emergency threads), no timeout required
Suitable for situations where you know the number of tasks and are not too busy
Because it is a core thread, it will not end the thread by itself after executing the task.
The number of core threads is 0, the maximum number of threads is Integer.MAX_VALUE, all created are emergency threads, and the lifetime is
It is 60s. Emergency threads can be created unlimitedly.
The queue is implemented using synchronousQueue and has no capacity limit.
Applicable to situations where multiple tasks are expected to be executed in queue order. Even if an exception is encountered, a new thread will be created to execute the remaining tasks.
Close thread pool
The thread pool status changes to SHUTDOWN and the submitted task is executed without blocking the execution of the calling thread.
The shutdown() method will modify the thread pool status, interrupt idle threads, and attempt to terminate
The thread pool status changes to STOP, and new tasks will not be accepted. The tasks in the queue will be returned, and the interrupt method is used to interrupt the executing tasks.
The shutdownNow() method will modify the thread pool status, interrupt all threads, obtain the remaining tasks in the queue, and try to terminate it.
Let limited worker threads take turns to process an unlimited number of tasks asynchronously
Applications of different task types use different thread pools, which can avoid starvation and improve efficiency.
- hunger Fixed-size thread pools may experience starvation The threads in the same thread pool all do the same task, and there are no remaining threads to do the following tasks, leading to starvation. Appear Let different thread pools do different tasks
- Thread pool size If it is too small, the thread cannot make full use of system resources and can easily lead to starvation. Excessive size leads to more thread context switching and takes up more memory. Determine the thread pool size according to different situations
- CPU-intensive operations (e.g. data analysis) Using CPU core number +1 can achieve optimal CPU utilization. +1 ensures that when the thread is suspended due to page missing failure or other problems, the additional thread can step in to ensure that the CPU clock cycle is not wasted.
- IO intensive CPU is not always busy Empirical formula: Number of threads = number of cores * expected CPU utilization * total time (CPU calculation time + waiting time) / CPU calculation time
- Task scheduling thread pool It can be implemented using Timer, which is simple and easy to use. However, all tasks are scheduled by one thread, so the tasks are executed serially. The delay or exception of one task will affect the subsequent tasks. Use newScheduledThreadPool instead. schedule (task, time, time unit) method to delay execution Construction method:
- Thread pool exception Exceptions will not be printed, and you need to try catch to catch them manually. The exception will be caught and printed through the get() method of the Future object
LimitLatch is used to limit current and control the maximum number of connections.
Acceptor receives new socket connections
Poller monitors the socket channel to see whether there are readable IO events. Once it is readable, it encapsulates a task object (socketProcessor) and submits it to the Executor thread pool for processing.
The worker threads in the Executor thread pool are responsible for processing requests
Tomcat thread pool extends ThreadPoolExecutor. If the total thread reaches maximumPoolSize, RejectExecutionException will not be thrown immediately. It will try to put the task into the queue again. If it fails, RejectExecutionException will be thrown.
- Fork/Join thread pool The idea of divide and conquer is used, which is suitable for CPU-intensive operations of task splitting. Multi-threading is added on the basis of divide and conquer, and the decomposition and merging of each task is handed over to different threads to complete. Step by step to improve computing efficiency By default, it is created in a thread pool with the same number of CPU cores. How to use: The task object needs to inherit RecursiveTask and override the compute() method