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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM