springboot使用多线程

一、使用ExecutorService

1、配置线程池数量

@Configuration
public class ThreadPoolConfig {

    @Bean
    public ExecutorService getThreadPool(){
        return Executors.newFixedThreadPool(8);
    }

}

2、service 使用方式。

@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    private ExecutorService executorService;

    @Override
    public User query() {
        executorService.execute(new Runnable() {
            public void run() {
                System.out.println("Asynchronous task");
            }
        });
        User user = new User();
        return user;
    }

}

二、通过配置类实现接口AsyncConfigurator,返回一个ThreadPoolTaskExecutor线程池对象。

1、配置异步类

  // ThredPoolTaskExcutor的处理流程
    // 当池子大小小于corePoolSize,就新建线程,并处理请求
    // 当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去workQueue中取任务并处理
    // 当workQueue放不下任务时,就新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理
    // 当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁

@Configuration
@EnableAsync  // 启用异步任务
public class AsyncConfiguration implements AsyncConfigurer {

    // 声明一个线程池(并指定线程池的名字)
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程数5:线程池创建时候初始化的线程数
        executor.setCorePoolSize(5);
        //最大线程数5:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(5);
        //缓冲队列500:用来缓冲执行任务的队列
        executor.setQueueCapacity(500);
        //允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60);
        //线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
        executor.setThreadNamePrefix("DailyAsync-");
        executor.initialize();
        return executor;
    }
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return AsyncConfigurer.super.getAsyncUncaughtExceptionHandler();
    }
}

2、实现方法

@Async注解表明该方法是异步方法,如果注解在类上,那表明这个类里面的所有方法都是异步的。

a、无返回值的方法

@Override
@Async
public User selectById(Long id) {
    User user = new User();
    user.setId(id);
    System.out.println("线程" + Thread.currentThread().getName() + " 执行异步任务:" + id);
    return user;
}

b、实现由返回值的方法

@Async
public Future<Long> subByAsync(Long id ) throws InterruptedException {
    long start = System.currentTimeMillis();
    long sum = 0;
    Thread.sleep(500);
    long end = System.currentTimeMillis();
    sum = end - start;
    System.out.println("线程" + Thread.currentThread().getName() + " 执行异步任务:" + id);
    return new AsyncResult<>(sum);
}

单元测试

@Test
public void selectByIdTest() {
    for (int i = 0; i < 10; i++) {
        iUserService.selectById((long)i);
    }
}

线程DailyAsync-1 执行异步任务:0
线程DailyAsync-2 执行异步任务:1
线程DailyAsync-3 执行异步任务:2
线程DailyAsync-4 执行异步任务:3
线程DailyAsync-5 执行异步任务:4
线程DailyAsync-2 执行异步任务:6
线程DailyAsync-1 执行异步任务:5
线程DailyAsync-5 执行异步任务:9
线程DailyAsync-3 执行异步任务:7
线程DailyAsync-4 执行异步任务:8



@Test
public void subByAsyncTest() throws ExecutionException, InterruptedException {
    for (int i = 0; i < 10; i++) {
        Future<Long> task = iUserService.subByAsync((long)i);
        long async = task.get();
        System.out.println("异步执行的时间是:" + async + "(毫秒)");
    }


}

线程DailyAsync-1 执行异步任务:0
异步执行的时间是:500(毫秒)
线程DailyAsync-2 执行异步任务:1
异步执行的时间是:500(毫秒)
线程DailyAsync-3 执行异步任务:2
异步执行的时间是:500(毫秒)
线程DailyAsync-4 执行异步任务:3
异步执行的时间是:500(毫秒)
线程DailyAsync-5 执行异步任务:4
异步执行的时间是:500(毫秒)
线程DailyAsync-1 执行异步任务:5
异步执行的时间是:500(毫秒)
线程DailyAsync-2 执行异步任务:6
异步执行的时间是:500(毫秒)
线程DailyAsync-3 执行异步任务:7
异步执行的时间是:500(毫秒)
线程DailyAsync-4 执行异步任务:8
异步执行的时间是:500(毫秒)
线程DailyAsync-5 执行异步任务:9
异步执行的时间是:500(毫秒)


 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值