Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.

preface

The core parameter configuration of thread pool has a lot of articles on the Internet, this time combined with personal understanding to write an article to record, in order to deepen the impression and follow-up reference.Copy the code

Thread pool configuration parameters

  • CorePoolSize: number of core threads in the thread pool
  • MaximumPoolSize: specifies the maximum number of threads in a thread pool
  • KeepAliveTime: allowed idle time for threads (collection of non-core worker threads)
  • TimeUnit: indicates the idle TimeUnit of a thread
  • WorkQueue: queue of threads (to which new tasks are put when the number of core threads is full)
  • ThreadFactory: threadFactory (used to create worker threads, custom threadFactory can specify thread names)
  • Handler: A thread pool rejection policy (a task rejection policy is executed when the thread queue is full and the maximum number of threads is full. There are four default types)
  • AllowCoreThreadTimeOut: Controls whether the core worker thread needs to be reclaimed

General thread pool parameter configuration

- First, I will ask an interview question: there are 1000 tasks, 10 servers, and each machine is 4-core. What is the most reasonable configuration of thread pool parameters without discarding tasks? - To break this down, 1000 tasks, 10 machines, then each machine is responsible for 100 tasks (normal rotation load balancing mode, not considering other extras), each machine is 4 cores, then you can set the number of core threads and the maximum number of threads to 4 and the thread queue size to 96. - It is also possible to set the maximum number of cores and threads to 5 (n+1), and the thread queue size to 95. This is to prevent threads from occasionally pausing due to missing pages or other reasons. The extra thread also ensures that the CPU's scheduling clock cycle is not wasted, equivalent to the standby thread.Copy the code
  • If the task is CPU-intensive: worker threads = number of CPU cores + 1;
  • If the task is IO intensive: Worker threads = number of CPU cores x 2;
  • So in the above example, thread pools are configured based on CPU-intensive tasks. And most articles on the web describe thread pool configurations based on these two points.
  • Unfortunately, the ideal is full, the reality is very skinny. Scenario in the practical work, and in fact it’s not that easy to distinguish between threads in the mission is CPU intensive or IO intensive, and there will be other applications on the server thread preemption CPU resources, even if there are some other formula configuration parameters of the thread pool, it is based on the ideal scenario for configuration, so the above configuration more or applied to the interview.

Dynamically configure thread pool parameters

  • Since it is not possible to define thread pool parameters suitable for all scenarios at one time, it is also possible to configure thread pool parameters dynamically according to different business scenarios to adapt most scenarios through manual intervention
  • Right in the JDK’s custom thread pool, ThreadPoolExecutor, provides methods to dynamically extend the core parameters of the thread pool
  • This method can be used in the thread pool at run time to override the previously configured value:

The ThreadPoolExecutor thread pool provides five configuration parameters that can be dynamically updated: the core thread pool, the maximum number of threads, the thread factory, the thread idle time, and the rejection policy.Copy the code
  • The core thread pool and the maximum thread pool parameters are discussed here:
/** * * @Author: ZRH * @Date: 2021/10/08 17:30 */ @Slf4j public class ExecutorTest { public static void main (String[] args) throws Exception { final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(7), new ThreadPoolExecutor.DiscardPolicy()); for (int i = 0; i < 10; i++) { threadPoolExecutor.execute(() -> { try { logExecutorInfo(threadPoolExecutor); Thread.sleep(2000); } catch (InterruptedException e) { } }); } logExecutorInfo(threadPoolExecutor); threadPoolExecutor.setCorePoolSize(5); threadPoolExecutor.setMaximumPoolSize(5); logExecutorInfo(threadPoolExecutor); Thread.currentThread().join(); } private static void logorInfo (ThreadPoolExecutor executor) {log.info(" threadpoolcore =" + executor.getCorePoolSize()) + ", thread pool threads biggest = "+ executor. GetMaximumPoolSize () +", thread pool queue tasks remaining = "+ executor. GetQueue (). The size () +", Thread pool threads active = "+ executor. GetActiveCount () +", thread pool task number "+ executor. GetCompletedTaskCount ()); }}Copy the code

  • The number of core threads in the pool is 2, the maximum number of threads is 3, and the remaining 7 threads are put into the queue. There are only three active threads.
  • After changing the number of core threads and the maximum number of threads to 5, the corresponding number of core threads and the maximum number of threads in the thread pool are also increased to 5, and the number of active worker threads is also 5. The configuration is changed successfully.
  • Note: When updating thread pool parameters, the number of core threads cannot exceed the maximum number of threads configured. Otherwise, the configuration does not take effect.
public static void main (String[] args) throws Exception {
    final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
            3,
            30,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(7),
            new ThreadPoolExecutor.DiscardPolicy());
    for (int i = 0; i < 10; i++) {
        threadPoolExecutor.execute(() -> {
            try {
                logExecutorInfo(threadPoolExecutor);
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        });
    }
    logExecutorInfo(threadPoolExecutor);
    threadPoolExecutor.setCorePoolSize(5);
    // threadPoolExecutor.setMaximumPoolSize(5);
    logExecutorInfo(threadPoolExecutor);
    Thread.currentThread().join();
}
Copy the code

  • In the figure above, update the number of core threads to 5 and leave the maximum number of threads unchanged at 3. The getTask() method of the ThreadPoolExecutor class is used to get three active threads. The getTask() method of the ThreadPoolExecutor class is used to get three active threads.

Dynamically update thread queues

  • ThreadPoolExecutor thread pools have no way to dynamically configure thread pool queue sizes
  • It’s easy to implement a custom queue, copy the LinkedBlockingQueue, and set the capacity parameter to changeable

public static void main (String[] args) throws Exception {
    final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
            3,
            30,
            TimeUnit.SECONDS,
            new CustomLinkedBlockingQueue<>(7),
            new ThreadPoolExecutor.DiscardPolicy());
    for (int i = 0; i < 10; i++) {
        threadPoolExecutor.execute(() -> {
            try {
                logExecutorInfo(threadPoolExecutor);
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        });
    }
    logExecutorInfo(threadPoolExecutor);
    threadPoolExecutor.setCorePoolSize(5);
    threadPoolExecutor.setMaximumPoolSize(5);
    CustomLinkedBlockingQueue queue = (CustomLinkedBlockingQueue)threadPoolExecutor.getQueue();
    queue.setCapacity(10);
    for (int i = 0; i < 10; i++) {
        threadPoolExecutor.execute(() -> {
            try {
                logExecutorInfo(threadPoolExecutor);
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        });
    }
    Thread.currentThread().join();
}
Copy the code

  • If the result shows that subsequent tasks are added to the queue and the size of the queue exceeds that of the first time, the configuration is successful

The last

  • Reference: Java thread pool implementation principle and its practice in Meituan business
  • Learn with an open mind and make progress together