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

原文地址:https://www.cnblogs.com/gongxr/p/13983950.html