1. 添加线程池配置
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
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.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Slf4j
@EnableAsync
@Configuration
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;
@Bean(name = "asyncServiceExecutor")
public Executor asyncServiceExecutor() {
log.warn("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setThreadNamePrefix(namePrefix);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
2. 添加配置 application.properties
# 异步线程配置
# 配置核心线程数
async.executor.thread.core_pool_size = 30
# 配置最大线程数
async.executor.thread.max_pool_size = 30
# 配置队列大小
async.executor.thread.queue_capacity = 99988
# 配置线程池中的线程的名称前缀
async.executor.thread.name.prefix = async-
3. 创建 AsyncService 和 AsyncServiceImpl 实例
import java.util.List;
import java.util.concurrent.CountDownLatch;
public interface AsyncService {
void executeAsync(List<OneTransOrder> results, OneTransOrderDao oneTransOrderDao, CountDownLatch countDownLatch);
}
@Service
@Slf4j
public class AsyncServiceImpl implements AsyncService {
@Override
@Async("asyncServiceExecutor")
public void executeAsync(List<OneTransOrder> results, OneTransOrderDao oneTransOrderDao, CountDownLatch countDownLatch) {
try{
log.warn("start executeAsync");
oneTransOrderDao.insertBatch(results);
log.warn("end executeAsync");
}finally {
countDownLatch.countDown();
}
}
}
4. 实现业务类的调用示例
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@Service("oneTransOrderService")
public class OneTransOrderServiceImpl extends ServiceImpl<OneTransOrderDao, OneTransOrder> implements OneTransOrderService {
@Resource
private AsyncService asyncService;
@Resource
private OneTransOrderDao oneTransOrderDao;
public int testMultiThread() {
List<OneTransOrder> oneTransOrders = oneTransOrderDao.selectList(new QueryWrapper<>());
List<List<OneTransOrder>> lists = ListUtil.split(oneTransOrders, 100);
CountDownLatch countDownLatch = new CountDownLatch(lists.size());
for (List<OneTransOrder> listSub:lists) {
asyncService.executeAsync(listSub, oneTransOrderDao,countDownLatch);
}
try {
countDownLatch.await();
} catch (Exception e) {
log.error("阻塞异常:"+e.getMessage());
}
return oneTransOrders.size();
}
}
5. 持久化层
public interface OneTransOrderDao extends BaseMapper<OneTransOrder> {
int insertBatch(@Param("entities") List<OneTransOrder> entities);
}
<!-- 批量插入 -->
<insert id="insertBatch" keyProperty="fId" useGeneratedKeys="true">
insert into OnePayOrder(music_id )
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.musicId})
</foreach>
</insert>