Spring ThreadPoolTaskExecutor use a custom thread pool and asynchronous calls

Multithreading has been a high-frequency point working knowledge or interview process today to share with you from using ThreadPoolTaskExecutor custom thread pool and asynchronous multi-threaded calls.

一、ThreadPoolTaskExecutor

In this paper, methods Executors factory configuration.

1, the thread pool parameters used to define the configuration file

Creating executor.properties file in the resources directory of the project, and add the following configuration:

# 异步线程配置
# 核心线程数
async.executor.thread.core_pool_size=5
# 最大线程数
async.executor.thread.max_pool_size=8
# 任务队列大小
async.executor.thread.queue_capacity=2
# 线程池中线程的名称前缀
async.executor.thread.name.prefix=async-service-
# 缓冲队列中线程的空闲时间
async.executor.thread.keep_alive_seconds=100

2, Executors factory configuration

2.1, configuration details
@Configuration
// @PropertySource是找的target目录下classes目录下的文件,resources目录下的文件编译后会生成在classes目录
@PropertySource(value = {"classpath:executor.properties"}, ignoreResourceNotFound=false, encoding="UTF-8")
@Slf4j
public class ExecutorConfig {

    @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;
    @Value("${async.executor.thread.keep_alive_seconds}")
    private int keepAliveSeconds;

    @Bean(name = "asyncTaskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        log.info("启动");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数
        executor.setCorePoolSize(corePoolSize);
        // 最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        // 任务队列大小
        executor.setQueueCapacity(queueCapacity);
        // 线程前缀名
        executor.setThreadNamePrefix(namePrefix);
        // 线程的空闲时间
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 线程初始化
        executor.initialize();
        return executor;
    }
}
2.2, explanatory notes
  • @Configuration: the Spring container at startup, will load the class annotated with @Configuration, wherein the method of processing with @Bean annotated.
  • @Bean: is the annotation on a method level, mainly used in @Configuration annotated class, it can also be used in @Component annotated class. Add the bean id is the method name.
  • @PropertySource: Loads the specified profile. value value to load the configuration file, ignoreResourceNotFound means that if you load the file is not found, the program whether to ignore it. The default is false. If true, the representatives of the loaded configuration file does not exist, the program is not being given. In the actual project development, it is best set to false. If file attributes application.properties custom configuration file attributes repeated, the custom property value is overwritten profile, loading a configuration file application.properties properties.
  • SLF4J @: Lombok log output tool, after add this note, you can directly call log output level of each log.
  • @Value: call the configuration file attributes and assigned a value to the property.
2.3 thread pool configuration instructions
  • The number of core threads: the thread pool to create a number of threads at initialization time. When the number of threads than the core number of threads, the thread over the task into the queue.
  • The maximum number of threads: Only after the task queue is full applications will exceed the number of core threads. Not be less than the core number of threads.
  • Task Queue: the number of threads is greater than the number of portions of the core thread into the task queue. If the task queue is large enough to exceed the number of threads in core thread will not be created, it will wait core thread has finished the task and then perform their own tasks task queue, and will not create additional threads. Example: If you have 20 tasks to be performed, the core number of threads: 10, maximum number of threads: 20, task queue sizes: 2. The system creates 18 threads. It has 18 threads executing the task, perform the task in the task queue.

  • Thread idle time: when the number of threads in the pool is greater than the core number of threads, if a thread is idle for more than keepAliveTime, the thread will be terminated. In this way, the thread pool can dynamically adjust the number of threads in the pool.
  • Refused strategy: if (the total number of tasks - the core number of threads - the number of job queue) - thread reject> 0, it appears - (core number of threads Maximum number of threads). Examples :( 12--5--2) - (8 - 5)> 0, the thread will be rejected. Thread refused further separated into four strategies, namely:
    • CallerRunsPolicy (): referred to the caller thread runs, such as the main thread.
    • AbortPolicy (): direct throw.
    • DiscardPolicy (): discarded.
    • DiscardOldestPolicy (): discard the oldest task in the queue.
2.4 thread pool configuration personal understanding
  • When a job is submitted to the thread pool, first check whether the thread pool threads are at the core mission. If not, choose a thread to perform the task.
  • If you are on a mission to see the task queue is full. If dissatisfied, the task will be stored in the job queue. After the core thread has finished the implementation of its mandate, the task will be re-processing tasks in the queue.
  • If the task queue is full, see the thread pool (the maximum number of threads control) is full. If dissatisfied, then create a thread to perform the task. If full, the task will not be performed in accordance with the policy processing.

Second, the calling thread asynchronously

ThreadPoolTaskExecutor is usually used together and @Async. Add @Async comment on a methodology to demonstrate that the method is asynchronous call function. Behind @Async plus thread pool method name or bean name, indicating asynchronous thread will load the configuration of the thread pool.

@Component
@Slf4j
public class ThreadTest {
    /**
     * 每10秒循环一次,一个线程共循环10次。
     */
    @Async("asyncTaskExecutor")
    public void ceshi3() {
        for (int i = 0; i <= 10; i++) {
            log.info("ceshi3: " + i);
            try {
                Thread.sleep(2000 * 5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

NOTE: Be sure to add @EnableAsync notes on startup class, so @Async annotations take effect.

Third, the use of multi-threaded scenarios

1, the timing task @Scheduled

// 在启动类上添加 @EnableScheduling 注解
@SpringBootApplication
@EnableScheduling
public class SpringBootStudyApplication {
   public static void main(String[] args) {
      SpringApplication.run(SpringBootStudyApplication.class, args);
   }
}
// @Component 注解将定时任务类纳入 spring bean 管理。
@Component
public class listennerTest3 {

    @Autowired
    private ThreadTest t;
    
    // 每1分钟执行一次ceshi3()方法
    @Scheduled(cron = "0 0/1 * * * ?")
    public void run() {
        t.ceshi3();
    }
}

ceshi3 () method calls the thread pool configuration, and asynchronous execution.

@Component
@Slf4j
public class ThreadTest {
    /**
     * 每10秒循环一次,一个线程共循环10次。
     */
    @Async("asyncTaskExecutor")
    public void ceshi3() {
        for (int i = 0; i <= 10; i++) {
            log.info("ceshi3: " + i);
            try {
                Thread.sleep(2000 * 5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

2, the program starts on a multi-threaded asynchronous execution

Achieved through inheritance CommandLineRunner class.

@Component
public class ListennerTest implements CommandLineRunner {

    @Autowired
    private ThreadTest t;

    @Override
    public void run(String... args) {
        for (int i = 1; i <= 10; i++) {
            t.ceshi();
        }
    }
}
@Component
@Slf4j
public class ThreadTest {

    @Async("asyncTaskExecutor")
    public void ceshi() {
        log.info("ceshi");
    }
}    

3, the definition of a http Interface

You can also call in the form of an asynchronous interface, multithreading:

@RestController
@RequestMapping("thread")
public class ListennerTest2 {

    @Autowired
    private ThreadTest t;

    @GetMapping("ceshi2")
    public void run() {
        for (int i = 1; i < 10; i++) {
            t.ceshi2();
        }
    }
}
@Component
@Slf4j
public class ThreadTest {

    @Async("asyncTaskExecutor")
    public void ceshi2() {
        for (int i = 0; i <= 3; i++) {
            log.info("ceshi2");
        }
    }
}    

4, the test class

@RunWith(SpringRunner.class)
@SpringBootTest
public class ThreadRunTest {

    @Autowired
    private ThreadTest t;

    @Test
    public void thread1() {
        for (int i = 1; i <= 10; i++) {
            t.ceshi4();
        }
    }
}
@Component
@Slf4j
public class ThreadTest {
    @Async("asyncTaskExecutor")
    public void ceshi4() {
        log.info("ceshi4");
    }
}

IV Summary

Above describes the configuration ThreadPoolTaskExecutor thread pool, use, significance and role of related notes, and also a brief introduction to the use of asynchronous calls @Async thread, and finally listed multithreaded usage scenarios, and accompanied by sample code. I hope you like it.


Guess you like

Origin www.cnblogs.com/createboke/p/11669241.html