Springboot之多线程举例
Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor。而实际开发中任务一般是非阻碍的,即异步的,所以我们要在配置类中通过@EnableAsync开启对异步任务的支持,并通过在实际执行的Bean的方法中使用@Async注解声明其是一个异步任务。
配置类
package com.gxr.imybatisplus.service.Thread; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; /** * @Description: 配置类实现AsyncConfigurer接口,并重写getAsyncExecutor方法,并返回一个ThreadPoolTaskExecutor, * 这样我们就获得一个基于线程池TaskExecutor - 基于Spring配置方式 * */ @Configuration @ComponentScan("com.gxr.imybatisplus.service.Thread") @EnableAsync public class CustomMultiThreadingConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); //如果池中的实际线程数小于corePoolSize,无论是否其中有空闲的线程,都会给新的任务产生新的线程 taskExecutor.setCorePoolSize(5); //queueCapacity 线程池所使用的缓冲队列 taskExecutor.setQueueCapacity(256); //连接池中保留的最大连接数。 taskExecutor.setMaxPoolSize(1024); //线程名称前缀 taskExecutor.setThreadNamePrefix("Application Thread-"); taskExecutor.initialize(); return taskExecutor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return AsyncConfigurer.super.getAsyncUncaughtExceptionHandler(); } }
多线程任务
package com.gxr.imybatisplus.service.Thread; import com.gxr.imybatisplus.entity.TSampleE; import com.gxr.imybatisplus.mapper.SampleEMapper; import com.gxr.imybatisplus.utils.GenObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.List; import java.util.logging.Logger; /** * @Description: 创建线程任务服务 - 基于Spring方式 */ @Service public class CustomMultiThreadingService { private final Logger logger = Logger.getLogger(this.getClass().getName()); @Autowired SampleEMapper sampleMapper; @Async public void insertOne(String tableName) { // sampleMapper = ApplicationContextProvider.getBean(SampleEMapper.class); int id = getNextId(tableName); TSampleE sample = GenObject.genSampleObj(id, tableName); sampleMapper.insertOne(sample); // logger.info(tableName + "插入成功!"); } @Async public void insertBatch(String tableName, int number) { // sampleMapper = ApplicationContextProvider.getBean(SampleEMapper.class); int id = getNextId(tableName); List<TSampleE> sampleList = GenObject.getSampleList(id, number, tableName); sampleMapper.insertList(sampleList, tableName); logger.info(tableName + "插入成功!总共" + number + "条"); } /** * 获取当前最大id值 */ private int getMaxId(String tableName) { int id; try { id = sampleMapper.getMaxID(tableName); } catch (NullPointerException e) { return 0; } return id; } /** * 获取下一条数据的id值 */ public int getNextId(String tableName) { return getMaxId(tableName) + 1; } }
测试执行
package com.gxr.imybatisplus.threadTest; import com.gxr.imybatisplus.service.Thread.CustomMultiThreadingService; import com.gxr.imybatisplus.service.Thread.MyThreadService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class ThreadTest { @Autowired CustomMultiThreadingService multiThreadingService; /** * 多线程测试 - 实现Runnable接口方式 */ @Test public void testThread() { String[] tableNames = {"t_sample_s_pg1", "t_sample_s_pg2"}; int number = 20; for (String name : tableNames) { new Thread(new MyThreadService(name, number)).start(); } } /** * 多线程测试 - 基于Spring配置方式 */ @Test public void testThread_spring() { String[] tableNames = {"t_sample_s_pg1", "t_sample_s_pg2"}; int number = 20; for (String name : tableNames) { multiThreadingService.insertBatch(name, number); } } }
参考文献:
https://www.cnblogs.com/onlymate/p/9686740.html
https://zhuanlan.zhihu.com/p/134636915