在SpringBoot或Spring中使用并发编程变得很简单了,如果开发者不定义线程池,SpringBoot或Spring会使用默认定义的线程池,如果用户自定义了线程池,则使用用户自定义的线程池。
我们来看如何在SpringBoot中使用自定义线程池进行并发编程。
1、SpringBoot启动类上添加异步@EnableAsync
代码:
@EnableAsync
@SpringBootApplication
public class MyspringbootApplication {
public static void main(String[] args) {
SpringApplication.run(MyspringbootApplication.class, args);
}
}
2、自定义线程池
代码:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
public class TaskExecutorConfig {
//@Bean("task-executor") //如果要自定义多个线程池,则指定自定义线程池的名称,方便业务代码指定使用的线程池
@Bean
public TaskExecutor taskExecutor(){
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(10);
taskExecutor.setMaxPoolSize(50);
taskExecutor.setQueueCapacity(100);
taskExecutor.setKeepAliveSeconds(300);
taskExecutor.setThreadNamePrefix("自定义-TaskExecutor");
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return taskExecutor;
}
}
3、编写测试代码Service方法
代码:
package com.itzhimei.itzhimei.executor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class ExecutorServiceImpl {
//@Async("task-executor") //括号中指定的就是要引用的线程池的名称
@Async
public void test() throws InterruptedException {
System.out.println("test start:"+Thread.currentThread().getName());
Thread.sleep(1000);
System.out.println("test end:"+Thread.currentThread().getName());
}
}
这里的重点是test()方法上的注解:@Async,这个注解的方法,spring检测到会自动使用线程池中的线程进行处理。
4、测试入口Controller
代码:
package com.itzhimei.itzhimei.executor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ExecutorController {
@Autowired
private ExecutorServiceImpl executorService;
@RequestMapping(value = "/executor/testAsync", method = RequestMethod.GET, produces = "application/json")
public String testAsync() throws InterruptedException {
executorService.test();
executorService.test();
executorService.test();
executorService.test();
executorService.test();
Thread.sleep(2000);
return "testAsync";
}
}
5、输出,测试地址接口:http://localhost:8080/executor/testAsync
test start:自定义-TaskExecutor5
test start:自定义-TaskExecutor4
test start:自定义-TaskExecutor1
test start:自定义-TaskExecutor2
test start:自定义-TaskExecutor3
test end:自定义-TaskExecutor3
test end:自定义-TaskExecutor2
test end:自定义-TaskExecutor5
test end:自定义-TaskExecutor4
test end:自定义-TaskExecutor1
我们从结果可以看到有5个线程在并发执行,线程名称也是我们自定义线程池定义的前缀名称:“自定义-TaskExecutor”。