Recently, I did a code review and found that many places have their own threads to use. Based on the requirements of Alibaba Java Development Manual, I simply recorded how to use thread pool in spring Boot project

There are roughly three ways to use threads. The first is to inherit Threat class and rewrite the run method in it. The second is to implement the Runnable interface and override the run method in it. The third way is to implement the Callable method and then call the FutureTask method in conjunction with the start() method.

However, in the well-known “Alibaba Java Development Manual”, it is clearly stipulated that users are not allowed to create threads by themselves, and must create threads through the thread pool. As for the reasons we all know, first, the creation of threads can be standardized, and the number of development threads can be controlled through relevant configuration. Second, the thread can be unified to the thread pool to manage, as we all know, Java has a lot of pool technology applications, including object pool, method pool and connection pool and so on, are to optimize the cost of resources and appear. Thread pools can’t be created by using Executors. Instead, use ThreadPoolExecutor. This is partly because the Executor framework in JDK provides methods to create thread pools such as newFixedThreadPool(), newSingleThreadExecutor(), and newCachedThreadPool(), but all of them have limitations and are not flexible enough. In addition, the previous methods are also implemented by using ThreadPoolExecutor internally. Using ThreadPoolExecutor can help you define the running rules of the thread pool, create a thread pool that meets the needs of your business scenario, and avoid the risk of resource exhaustion. In our Spring Boot project, ThreadPoolTaskExecutor, the thread pool that Spring provides to encapsulate ThreadPoolExecutor, can be enabled directly with annotations.

  • First, we add the configuration of thread pool to the YML file, as follows:
Async: executor: thread: core_pool_size:5# configure the maximum number of threads max_pool_size20Queue_capacity:20Name: prefix: async-service-Copy the code

Add the configuration class ThreadPoolConfiguration

@Configuration
@EnableAsync
@Slf4j
public class ThreadPoolConfiguration {

    @Value("${async.executor.thread.core_pool_size}")
    private int corePoolSize;
    @Value("${async.executor.thread.max_pool_size}")
    private int maxPoolSize;
    @Value("${async.executor.thread.queue_capacity}")
    private int queueCapacity;
    @Value("${async.executor.thread.name.prefix}")
    private String namePrefix;

    @Bean(name = "asyncServiceExecutor")
    public Executor asyncServiceExecutor(a) {
        log.info("start asyncServiceExecutor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // Set the number of core threads
        executor.setCorePoolSize(corePoolSize);
        // Set the maximum number of threads
        executor.setMaxPoolSize(maxPoolSize);
        // Configure the queue size
        executor.setQueueCapacity(queueCapacity);
        // Configure the thread name prefix in the thread pool
        executor.setThreadNamePrefix(namePrefix);

        Rejection -policy: how to deal with a new task when the pool reaches Max size
        / / new ThreadPoolExecutor. AbortPolicy () the default thread pool refusal strategies, at the time of tasks cannot be submitted, throw an exception
        . / / new ThreadPoolExecutor DiscardPolicy discarding the task (), but does not throw an exception. If the thread queue is full, all subsequent submitted tasks are discarded silently.
        / / new ThreadPoolExecutor. DiscardOldestPolicy () discard queue in front of the task, and then resubmit the rejected tasks.
        . / / new ThreadPoolExecutor CallerRunsPolicy () by the calling thread to handle the task
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // Perform initialization
        executor.initialize();
        returnexecutor; }}Copy the code

Create a Service interface AsyncService and its implementation class

public interface AsyncService {
    /** * send notification email *@paramMail Indicates the email address *@paramContent Email content */
    void sendMail(String mail,String content);
}

@Slf4j
@Service
@RequiredArgsConstructor
public class AsyncServiceImpl implements AsyncService {
    final private IMailService mailService;

    @Override
    public void sendMail(String mail,String content) {
        mailService.sendSimpleEmail(mail, "Email Subject", content); }}Copy the code

Async(“asyncServiceExecutor”) to the executeAsync() method. The asyncServiceExecutor method is the name of the previous executorConfig.java method. Indicates that the thread pool entered by the executeAsync method is created by the asyncServiceExecutor method. The next step is to inject the Service in the Controller or wherever it is used via @autoWired and use it directly. Finally, you can test the interface through postMan batch requests.