SPRING ThreadPoolTaskExecutor示例

0、前言

当我们需要实现并发、异步等操作时,通常都会使用到ThreadPoolTaskExecutor。它是springcore包中的,而ThreadPoolExecutor是JDK中的JUC。ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了封装处理。

1、示例一

1.1、配置类

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;

@EnableAsync
@Configuration
public class ExecutorConfig {

    @Bean(name = "asyncServiceExecutor")
    public Executor asyncServiceExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        executor.setCorePoolSize(10);
        //设置最大线程数
        executor.setMaxPoolSize(30);
        //设置队列大小
        executor.setQueueCapacity(50);
        //配置线程池的前缀
        executor.setThreadNamePrefix("async-service-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //设置空闲时间
        executor.setKeepAliveSeconds(60);
        //进行加载
        executor.initialize();
        return executor;
    }
}

1.2、应用

1.2.0 需异步的方法

import com.baomidou.mybatisplus.extension.service.IService;
import com.chengd.pojo.GeneCase;


public interface GeneCaseService extends IService<GeneCase>
{

    void testThread() throws InterruptedException;
}

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chengd.mapper.GeneCaseMapper;
import com.chengd.pojo.GeneCase;
import com.chengd.service.GeneCaseService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class GeneCaseServiceImpl extends ServiceImpl<GeneCaseMapper, GeneCase> implements GeneCaseService {

    @Override
    @Async
    public void testThread() throws InterruptedException {
        for (int i = 0; i < 200; i++) {
            System.out.println("副线程名称 " + Thread.currentThread().getName() + " === " + i);
            Thread.sleep(5);
        }
    }

}

1.2.1 Controller

import com.chengd.common.Result;
import com.chengd.service.TestService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/test")
@Api(tags = "测试ThreadPoolTaskExecutor")
public class TestController {

    @Resource
    private TestService testService;

    @GetMapping("/thread")
    public Result<Object> testThread() throws InterruptedException {
        testService.testThread();
        return Result.succeed("请求成功");
    }
}

1.2.2 Service

public interface TestService {

    /**
     * 测试Thread
     */
    void testThread() throws InterruptedException;

}
import com.chengd.service.GeneCaseService;
import com.chengd.service.TestService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class TestServiceImpl implements TestService {

    @Resource
    private GeneCaseService geneCaseService;

    @Resource(name = "asyncServiceExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
    public void testThread() throws InterruptedException {

        threadPoolTaskExecutor.submit(()-> {
            try {
                test();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        threadPoolTaskExecutor.submit(() -> {
            try {
                geneCaseService.testThread();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });


        for (int i = 0; i < 200; i++) {
            System.out.println("主线程名称 " + Thread.currentThread().getName() + " === " + i);
            Thread.sleep(5);
        }

    }

    @Async
    void test() throws InterruptedException {
        for (int i = 0; i < 200; i++) {
            System.out.println("jei线程名称 " + Thread.currentThread().getName() + " === " + i);
            Thread.sleep(5);
        }
    }
}

1.3、测试结果

注意事项:
配置类的 @EnableAsync
需异步方法的 @Async

2、示例二

2.1、配置类

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@Configuration
public class AsyncTaskExecutePool implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程池大小
        executor.setCorePoolSize(AsyncTaskProperties.corePoolSize);
        //最大线程数
        executor.setMaxPoolSize(AsyncTaskProperties.maxPoolSize);
        //队列容量
        executor.setQueueCapacity(AsyncTaskProperties.queueCapacity);
        //活跃时间
        executor.setKeepAliveSeconds(AsyncTaskProperties.keepAliveSeconds);
        //线程名字前缀
        executor.setThreadNamePrefix("el-async-");
        // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
        // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (throwable, method, objects) -> {
            log.error("====" + throwable.getMessage() + "====", throwable);
            log.error("exception method:" + method.getName());
        };
    }
}

2.2、应用

①项目结构与示例一相同

②与示例一实现类不同:

import com.chengd.service.GeneCaseService;
import com.chengd.service.TestService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class TestServiceImpl implements TestService {

    @Resource
    private GeneCaseService geneCaseService;

//    @Resource(name = "asyncServiceExecutor")
//    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
    public void testThread() throws InterruptedException {

        threadPoolTaskExecutor.submit(()-> {
            try {
                test();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        threadPoolTaskExecutor.submit(() -> {
            try {
                geneCaseService.testThread();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });


        for (int i = 0; i < 200; i++) {
            System.out.println("主线程名称 " + Thread.currentThread().getName() + " === " + i);
            Thread.sleep(5);
        }

    }

    @Async
    void test() throws InterruptedException {
        for (int i = 0; i < 200; i++) {
            System.out.println("jei线程名称 " + Thread.currentThread().getName() + " === " + i);
            Thread.sleep(5);
        }
    }
}

2.3、测试结果

posted @   南翔技校毕业后  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结
点击右上角即可分享
微信分享提示