Super detailed Springboot thread pool usage one (for personal use)

Table of contents

foreword

(1) @EnableAsync and @Async are critical

(2) Thread and Runnable should be cautious

(3) Data type, thread safety should be kept in mind

(4) @Configuration and @Bean are very convenient

(5) How to choose ThreadPoolExecutor and ThreadPoolTaskExecutor

(6) Talent!


foreword

        The thread pool, as the name suggests, can be compared to a pool, and each thread is like the water in the pool. Therefore, the size of the pool depends on the system hardware configuration, so I won’t go into details here.

        Of course, other developers have also made suggestions on setting the size of the thread pool:

Setting the thread pool size

        In response to this problem, the first thing we need to confirm is whether our needs are computing-intensive or IO-intensive.

        If it is computationally intensive, the ideal solution is: number of threads = number of CPU cores + 1, or it can be set to number of CPU cores * 2, generally set CPU * 2

        If it is IO-intensive, the number of threads = number of CPU cores/(1-blocking coefficient), the group competition coefficient is generally between 0.8 and 0.9, and can also be 0.8 or 0.9.
———————————— ————
Copyright statement: This article is an original article of CSDN blogger "one_smail", following the CC 4.0 BY-SA copyright agreement, please attach the original source link and this statement for reprinting.
Original link: https://blog.csdn.net/qq_40386113/article/details/127581333

(1) @EnableAsync and @Async are critical

@EnableAsync // 这注解允许异步

@Async // 这注解的函数会被异步处理

        The role of the thread pool is largely for concurrent and efficient processing of tasks. The asynchronous processing tasks can effectively improve the throughput of processing tasks.

(2) Thread and Runnable should be cautious

        Thread can also create threads, but thread resources need to be destroyed and recycled after the thread is used up. This itself consumes a lot of resources, and it is easy to cause thread context switching problems, and even improper thread management may easily lead to resource exhaustion. Therefore, when you need to use threads, you must choose Thread carefully.

(3) Data type, thread safety should be kept in mind

        If there are multiple ways to share data across threads, keep in mind the thread-safe data types for various usage scenarios. like:

  1.  AtomicInteger atomic int integer;
  2.  AtomicLong atomic long integer;
  3.  AtomicBoolean atomic boolean;
  4. All three types of List are thread-safe:
    1. List<T> vector = new Vector<>();
    2. List<T> listSyn = Collections.synchronizedList(new ArrayList<>());
    3. List<T> copyList = new CopyOnWriteArrayList<>();

(4) @Configuration and @Bean are very convenient

@Configuration 注解的配置类

@Bean 将实例对象提交给IoC容器

        The combination of this pair allows us to ignore the management of instance objects and focus more on business development.

        It is also worth pointing out that  @Autowired (required = true)  automatically assembles the instance object; if you do not want to be automatically assembled, then required = false.

(5) How to choose ThreadPoolExecutor and ThreadPoolTaskExecutor

        First of all, these two thread pool methods are essentially the same. The source code of ThreadPoolTaskExecutor adds a layer of packaging on ThreadPoolExecutor to make it easier to use in the spring framework. And here only talk about ThreadPoolTaskExecutor.

(6) Talent!

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

@EnableAsync
@Configuration
public class ThreadPoolCfg {
    // 获取服务器的cpu个数
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    // 核心线程数量
    private static final int COUR_SIZE = CPU_COUNT * 2;
    // 线程最大数量
    private static final int MAX_COUR_SIZE = COUR_SIZE * 4;

    // 提交给IoC容器,装配名称为 "threadPoolTaskExecutor"
    @Bean("threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor taskExecutor(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        // 核心线程数量
        threadPoolTaskExecutor.setCorePoolSize(COUR_SIZE);
        // 最大线程数
        threadPoolTaskExecutor.setMaxPoolSize(MAX_COUR_SIZE);
        // 线程缓冲任务队列
        threadPoolTaskExecutor.setQueueCapacity(MAX_COUR_SIZE * 2);
        // 线程空闲时间
        threadPoolTaskExecutor.setKeepAliveSeconds(60);
        // 线程名称前缀
        threadPoolTaskExecutor.setThreadNamePrefix("taskExecutor-");
        // 线程拒绝任务处理策略:没精力处理时,直接拒绝任务;若执行程序已被关闭,则直接丢弃
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return threadPoolTaskExecutor;
    }
}
// 这是个测试
public void test() {
    for (int i = 0; i < 10; i++){
        taskExecutor.execute(this::do_test);
    }
     System.out.println("main thread:" + Thread.currentThread().getName());
}

@Async("threadPoolTaskExecutor")
public void do_test() {
    System.out.println("thread name:" + Thread.currentThread().getName());
}

 The following are the test results, and you can clearly see the difference in threads.

Guess you like

Origin blog.csdn.net/qq_15855921/article/details/130078327