If the number of concurrent requests is very large, but the execution time of each thread is very short, threads will be created and destroyed frequently, which will greatly reduce the efficiency of the system. That’s what thread pools are for. Thread pools provide a solution to the overhead and under-resourcing problems of the thread life cycle. By reusing threads for multiple tasks, the overhead of thread creation is spread over multiple tasks.

Thread pool main flow

The user submits a task through Submit, and the thread pool will execute the following process:

  1. Check whether the number of running workers exceeds corePoolSize. If not, check whether the number of running workers exceeds corePoolSize. Create a worker to perform the task directly. — Thread pools start with no workers running
  2. If the number of running workers exceeds or equals corePoolSize, the task is added to the workQueue.
  3. If the workQueue is full (the offer method returns false), check if the number of workers currently running is less than maximumPoolSize, and if so, create a worker to execute the task directly.
  4. If the number of workers currently running is greater than or equal to maximumPoolSize, run RejectedExecutionHandler to reject the task submission.
  5. WorkQueue: A blocking queue that caches Runnable tasks to be executed. Threads poll the queue to obtain the execution of the tasks. You can choose from the following blocking queues:
    1. ArrayBlockingQueue: ArrayBlockingQueue is a bounded blocking queue based on an array structure that sorts elements in FIFO (first-in, first-out) order.
    2. LinkedBlockingQueue: A blocking queue based on a linked list structure that sorts elements in FIFO (first in, first out) and typically has a higher throughput than ArrayBlockingQueue. Static factory methods Executors. NewFixedThreadPool () using the queue.
    3. SynchronousQueue: A blocking queue that does not store elements. Each insert operation must wait until another thread calls to remove operation, otherwise the insert has been in the blocking state, the throughput is usually more than LinkedBlockingQueue, static factory methods Executors. NewCachedThreadPool using the queue.
    4. PriorityBlockingQueue: An infinite blocking queue with a priority.

Thread pool saturation strategy

Note: When the thread pool’s saturation policy, when the blocking queue is full and there are no idle worker threads, if the task continues to be submitted, a policy must be adopted to process the task. The thread pool provides four policies:

  1. ThreadPoolExecutor. AbortPolicy: discard task and throw RejectedExecutionException anomalies.
  2. ThreadPoolExecutor. DiscardPolicy: discard task too, but I don’t throw an exception.
  3. ThreadPoolExecutor. DiscardOldestPolicy: discard queue in front of the task, and then to try to perform a task (repeat)
  4. ThreadPoolExecutor. CallerRunsPolicy: handle the tasks by the calling thread

Thread pool states (5 types) :

The AtomicInteger variable CTL is very powerful: the low 29 bits represent the number of threads in the thread pool, and the high 3 bits represent the running status of the thread pool:

  1. RUNNING: -1 << COUNT_BITS, the thread pool in this state receives new tasks and processes tasks in the blocking queue;
  2. COUNT_BITS: 0 << COUNT_BITS, that is, the high three bits are 000. The thread pool in this state will not receive new tasks, but will process tasks in the blocking queue.
  3. STOP: 1 << COUNT_BITS, i.e. 001, the thread in this state does not receive new tasks, does not process tasks in the blocking queue, and interrupts running tasks.
  4. TIDYING: 2 << COUNT_BITS, i.e. 010, which indicates that the thread pool is TIDYING and optimizing the thread.
  5. TERMINATED: 3 << COUNT_BITS, or the high three bits are 011. This state indicates that the thread pool is stopped working.

How do I create a thread pool

Executors factory class

  1. Executors.newCachedThreadPool(); Note: Create a cacheable thread pool, if the length of the thread pool exceeds the processing needs, you can flexibly reclaim idle threads, if none, create a new thread.
  2. Executors.newFixedThreadPool(int); Description: Create a fixed length thread pool, can control the maximum number of concurrent threads, exceeding the threads will wait in the queue.
  3. Executors.newSingleThreadExecutor(); Description: Create a single threaded thread pool, which will only use a single worker thread to execute tasks, ensuring that all tasks are executed in order.
  4. Executors.newScheduledThreadPool(int); Create a fixed – length thread pool to support scheduled and periodic task execution.

Disadvantages:

  1. FixedThreadPool and SingleThreadPool:

The allowed queue length is integer. MAX_VALUE, which may accumulate a large number of requests and result in OOM. 2. CachedThreadPool and ScheduledThreadPool: The number of threads allowed to be created is integer. MAX_VALUE.

ThreadPoolExecutor

Although Executors provide the following tools, there may still be OOM problems. We generally recommend using the SDK’s internal thread pool to create the Executors, so that users can understand the meaning of each parameter to prevent problems. The constructor for creating a thread pool is provided within the SDK as follows:

/** * @param corePoolSize: number of core threads; * @param maximumPoolSize: the maximum number of threads allowed in the thread pool; * @param keepAliveTime: keepAliveTime (keepAliveTime) : keepAliveTime (keepAliveTime) : keepAliveTime (keepAliveTime); * @param unit: time unit; * @param workQueue: a queue for tasks that have already been submitted and are about to be executed; * @param threadFactory: threadFactory, used to create threads in the thread pool; * @ param handler: rejection policies, thread pool closed, or the maximum number of threads and queue is saturated, throw RejectedExecutionException exception; public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { }Copy the code