Art Java concurrent programming (XII) - thread pool

The benefits of using a thread pool

  • reduce the loss of resources . Re-use the created threads, reducing the overhead of thread creation and destruction.
  • improve the response speed . When the task comes, the created thread can immediately handle new tasks, without waiting for the implementation of the task thread is created before.
  • easy management of threads . A thread is a scarce resource, create too many threads may reduce the stability of the system, the thread pool can control the number of threads created, and its monitoring, management, tuning to improve system stability.

Thread pool process flow

  • 1. The new task comes, if the number of threads in the thread pool is less than the number of basic threads, create new threads to handle new tasks (this time even if there is a free thread pool thread, but also to create a new thread); on the contrary, the the next step.
  • 2. When the arrival of a new task, while the number of threads in the thread pool is substantially greater than or equal to the number of threads, the new task will be added to the blocked queue waiting to be processed. After blocking the queue is full, the next step.
  • 3. When the queue is full, and the new task comes, then create a new thread to perform the task. If the thread pool thread has reached the maximum number of threads (which means no longer be able to create threads), the next step.
  • 4. handled by the task saturation strategy.

Use the thread pool

Create a thread pool

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, runnableTaskQueue, handler);
复制代码
  • ● corePoolSize: Basic number of threads, basically represents the size of the thread pool. When the number of worker threads in the thread pool is less than the basic number of threads, always creates a new thread to handle the new tasks. If the calling thread pool prestartAllCoreThreads (), the thread pool will be created in advance all the basic threads.
  • ● maximumPoolSize: maximum number of threads, thread pool represents the maximum number of threads that can be created. When the number of threads in the task queue is full, and you have created less than the maximum number of threads, the thread pool creates a new thread to perform the task. It should be noted that for unbounded queue, the value is invalid.
  • ● keepAliveTime: In addition to basic thread pool thread, the thread of remaining idle keep-alive time. After more than this time, the idle thread will be terminated.
  • ● timeUnit: keep alive thread units, optionally units of one day (DAYS), h (HOURS), min (MINUTES), ms (MILLSECONDS), microsecond (MICROSECONDS), ns (nanoseconds).
  • ● runnableTaskQueue: task queue, when the basic thread in the pool in carrying out its mandate, the new task will be added to the task queue waiting to be executed. The queue has the following options:
    • 1.ArrayBlockingQueue : array-based bounded blocking queue, FIFO.
    • 2.LinkedBlockingQueue : Based on the list of unbounded blocking queue, FIFO, throughput is usually higher than ArrayBlockingQueue, static factory method Executors.newFixedThreadPool () uses this queue.
    • 3.SynchronousQueue : a blocking queue element is not stored. Each insert operation must wait until another thread calls the removal operation, or insert operation has been in a blocked state, throughput is usually higher than LinkedBlockingQueue, static factory method Executors.newCachedThreadPool use this queue.
    • 4.PriorityBlockingQueue : a priority queue having a wireless blocked. ● handler: saturation strategy, when queues and thread pools are full, the new task submitted for processing through the saturation strategy. Saturation strategy has the following four:
      • ①.AbortPolicy : default policy, the role is a direct throw.
      • ②.CallerRunsPolicy : only where the thread to run the task with the caller.
      • ③.DiscardOldestPolicy : discard queue recent task and execute the current task.
      • ④.DiscardPolicy : no treatment, discarded.

Submit jobs to the thread pool

You can use two methods to submit tasks to the thread pool, respectively execute () and submit () method.

  • ● execute (): the task is not required to submit a return value, can not determine whether the task is executed successfully thread pool.
  • ● submit (): used to submit the required return mission value, the return value is a Future type of object, the object can be determined whether the task is executed successfully, and Future by this type of object get () method can block until the current thread the task is successful, the method will return a value.

Close the thread pool

You can close the thread pool thread pool by calling shutdown () or shutdownNow () method. Their principle is by traversing the thread pool thread, and then one by one thread calls interrupt () method to interrupt the thread. Both of these approaches there is a difference:

  • shutdown (): This method interrupt thread does not perform a task, do not interrupt thread is performing a task.
  • shutdownNow (): This method interrupt thread is executing all tasks or paused.

The rational allocation of thread pool

Nature of the tasks can be divided into: CPU-intensive tasks, IO-intensive tasks, the hybrid mission. Configure thread pool task characteristics need to be considered.


  • ● CPU-intensive tasks: should allocate as small thread pool, such as thread pool size configured CPU cores + 1, so can avoid the overhead of thread context switching frequently caused.
  • ● IO-intensive tasks: should allocate the largest possible pool of threads, such as thread pool size configured CPU cores * 2, because the IO-intensive tasks less CPU usage, create more threads can increase CPU utilization rate.
  • ● Mixed tasks: tasks can be split people CPU-intensive tasks and IO-intensive tasks, then using two thread pool to handle, only the execution time of two minutes after the completion of tasks or less, then execute than serial execution to efficiently. When the two task execution time difference between the larger, faster implementation of the party to wait for slow implementation of the party, in terms of efficiency and not much improvement.

ThreadPoolExecutor operating mechanism

When ThreadPoolExecutor execute execute () method to add new tasks, operation mechanism is as follows:

  • 1. If the thread pool thread running less than corePoolSize, even with idle threads will create a new thread to perform the task.
  • 2. If the running thread in the thread pool is greater than or equal to corePoolSize, put the new task added to the queue.
  • 3. If the queue is full and the number of threads running less than maximumPoolSize, creating a new thread to perform the task.
  • 4. When the queue is full and the maximum number of threads running maximumPoolSize, performs saturation policy.

  • Note: Creating a new thread needs to acquire a global lock (the larger operating expenses), ThreadPoolExecutor taking the above design ideas, in order to avoid global lock acquisition possible. In general, when the number of threads in the thread pool is greater than or equal corePoolSize running, multi-task execution queue waiting to be added to, rather than directly processing task to create threads, so to avoid the global lock acquisition.

Guess you like

Origin juejin.im/post/5d16bc7ee51d45108223fca8