Create a custom thread pool (how to set the maximum number of threads?)

CPU intensive IO intensive

1: CPU intensive:

Definition: CPU intensive also refers to calculation intensive. Programs that spend most of their time doing CPU actions such as calculation logic judgment are called CPU intensive tasks. This type of task requires a lot of calculation, which mainly consumes CPU resources. Although this kind of computing intensive task can also be completed by multitasking, the more tasks, the more time spent in task switching, and the lower the efficiency of CPU executing tasks. Therefore, to make the most efficient use of CPU, the number of computing intensive tasks simultaneously should be equal to the number of CPU cores.

 

Features:

01: it is used when the CPU utilization rate is high (that is, it often computes some complex operations, logic processing, etc.) and very much

02: for a single machine, the maximum number of threads generally only needs to be set as the number of CPU cores

03: this type often occurs in some complex business calculation and logic processing processes in development.

Code example:

 1 package pool;
 2 
 3 import java.util.concurrent.Executors;
 4 import java.util.concurrent.LinkedBlockingDeque;
 5 import java.util.concurrent.ThreadPoolExecutor;
 6 import java.util.concurrent.TimeUnit;
 7 
 8 public class Demo02 {
 9     public static void main(String[] args) {
10         //Custom thread pool! Only used in work ThreadPoolExecutor
11 
12         /**
13          * How to define the maximum thread (how to set the maximum size of thread pool!)
14          * 1,CPU  Intensive, several cores, just a few, can maintain the highest efficiency of the CPU!
15          */
16 
17         //Get a computer CPU Number of cores
18         System.out.println(Runtime.getRuntime().availableProcessors());    //8 nuclei
19 
20         ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
21                 2,                                        //Core thread pool size
22                 Runtime.getRuntime().availableProcessors(),   //Maximum core thread pool size( CPU Intensive, according to CPU Core number setting)
23                 3,                                       //It's time-out, no one calls it and it's released
24                 TimeUnit.SECONDS,                             //Timeout unit
25                 new LinkedBlockingDeque<>(3),                 //Blocking queue
26                 Executors.defaultThreadFactory(),             //Thread factory, which is used to create threads, usually does not need to be moved
27                 new ThreadPoolExecutor.AbortPolicy());        //The bank is full. Someone else comes in. If you don't handle this person's, throw an exception
28 
29         try {
30             //Maximum load capacity, Deque + Max    (Number of queue threads+Maximum threads)
31             //Beyond throw RejectedExecutionException abnormal
32             for (int i = 1; i <= 9; i++) {
33                 //After using thread pool, use thread pool to create threads
34                 threadPool.execute(()->{
35                     System.out.println(Thread.currentThread().getName()+" ok");
36                 });
37             }
38         } catch (Exception e) {
39             e.printStackTrace();
40         } finally {
41             //Thread pool out, program end, close thread pool
42             threadPool.shutdown();      //(To ensure shutdown, place the shutdown method in the finally Medium)
43         }
44     }
45 }

 

2: IO intensive:

Definition: IO intensive tasks refer to tasks that need to perform a large number of IO operations, involving network and disk IO operations, with less CPU consumption. The main resource consumed is Io.

The IO we are exposed to can be roughly divided into two types: disk IO and network io.

01: disk IO is mostly for disk read and write operations. The most common is file read and write. If your database and Redis are also local, then this also belongs to disk IO.

02: network IO, which should be more familiar to you. We will encounter various network requests, such as http request, remote database reading and writing, remote Redis reading and writing, etc.

The characteristic of IO operation is that it needs to wait. We request some data, and the other side writes the data to the buffer. During this period, the thread that needs to read the data has nothing to do at all, so we can let out the CPU time slice until the buffer is full.

In this case, IO intensive tasks actually have a lot of optimization space (after all, there is waiting):

CPU utilization is low, there will be a lot of I/O operation time in the program, which leads to a lot of thread free time, so it is usually necessary to open twice the number of CPU core threads. When the thread is idle for I/O operation, the higher the percentage of thread waiting time is, the more threads are needed. Enable other threads to continue to use the CPU, so as to improve the utilization rate of CPU. The higher the percentage of thread CPU time is, the less threads are needed. This type mainly appears in some logic with frequent calculation business in development.

Code example:

 1 package pool;
 2 
 3 import java.util.concurrent.Executors;
 4 import java.util.concurrent.LinkedBlockingDeque;
 5 import java.util.concurrent.ThreadPoolExecutor;
 6 import java.util.concurrent.TimeUnit;
 7 
 8 public class Demo02 {
 9     public static void main(String[] args) {
10         //Custom thread pool! Only used in work ThreadPoolExecutor
11 
12         /**
13          * How to define the maximum thread (how to set the maximum size of thread pool!)
14          * 2,IO   Intensive > judge the IO consuming threads in your program
15          *      Program 15 large task io very occupy resources! (the maximum number of threads is set to 30)
16          *      Set the maximum number of threads to twice the number of io resource consuming threads
17          */
18 
19         //Get a computer CPU Number of cores
20         System.out.println(Runtime.getRuntime().availableProcessors());   //8 nuclei
21 
22         ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
23                 2,                               //Core thread pool size
24                 16,                     //If one IO Intensive programs have 15 large tasks and io It takes up a lot of resources! (the maximum number of threads is set to 2*CPU Number)
25                 3,                                //It's time-out, no one calls it and it's released
26                 TimeUnit.SECONDS,                 //Timeout unit
27                 new LinkedBlockingDeque<>(3),     //Blocking queue
28                 Executors.defaultThreadFactory(),               //Thread factory, which is used to create threads, usually does not need to be moved
29                 new ThreadPoolExecutor.DiscardOldestPolicy());  //The queue is full, try to compete with the earliest, and no exception will be thrown
30 
31         try {
32             //Maximum load capacity, Deque + Max    (Number of queue threads+Maximum threads)
33             //Beyond throw RejectedExecutionException abnormal
34             for (int i = 1; i <= 9; i++) {
35                 //After using thread pool, use thread pool to create threads
36                 threadPool.execute(()->{
37                     System.out.println(Thread.currentThread().getName()+" ok");
38                 });
39             }
40         } catch (Exception e) {
41             e.printStackTrace();
42         } finally {
43             //Thread pool out, program end, close thread pool
44             threadPool.shutdown();      //(To ensure shutdown, place the shutdown method in the finally Medium)
45         }
46     }
47 }

 

Next, we will analyze one by one:

1: For businesses with high concurrency and short task execution time, the number of threads in the thread pool can be set to the number of CPU cores + 1 to reduce thread context switching

2: Businesses with low concurrency and long task execution time need to be distinguished:

a) if the business time is long and concentrated on IO operations, that is, IO intensive tasks, because IO operations do not occupy the CPU, so do not let all CPUs idle, you can appropriately increase the number of threads in the thread pool, so that the CPU can handle more business

b) if the business time is long and concentrated on the calculation operation, that is, the calculation intensive task, there is no way. The number of threads in the thread pool is set less to reduce the thread context switching

(in fact, it can be seen from one or two that whether the concurrency is high or not, the current premise for judging whether the business is cpu intensive or I/O intensive is that you need to optimize the performance.)

3: With high concurrency and long service execution time, the key to solve this type of task is not the thread pool but the design of the overall architecture. It is the first step to see whether some data in these businesses can be cached. When our project uses redis as the cache (this kind of non relational database is still good). Adding servers is the second step (the first step for general government projects, because there is no need to make major changes to the project technology, and to seek a stable one, but the premise is sufficient funds). For the setting of thread pool, please refer to 2. Finally, the problem of long business execution time may also need to be analyzed to see if middleware can be used to split and decouple tasks (if the task time is too long, the splitting logic can be put into the queue and other operations).

 

3, : Summary:

01: a program that focuses on calculation (CPU intensive program). When multithreading runs, it can make full use of all the CPU cores. For example, when eight cores are opened, it can run eight threads at the same time, which is the maximum efficiency. However, if the number of threads far exceeds the number of CPU cores, the task efficiency will be reduced, because frequent thread switching also takes time. So for CPU intensive tasks, it's best to have threads equal to the number of CPUs.

02: if it is a disk or network based program (IO intensive program), when one thread is waiting for IO, the other thread can run in the CPU. Sometimes the CPU is idle, and all threads are waiting for Io. At this time, they are at the same time, while single thread is still waiting for Io. We all know that IO is slower than CPU. At this time, it is optimal that the number of threads equals twice the number of CPU cores.

Keywords: Java network less Database

Added by Arez on Sun, 28 Jun 2020 09:04:04 +0300