SpringBoot异步任务详解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Mr_FLM/article/details/92780963

SpringBoot版本

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>

定义异步任务

package com.ming.asyncservice;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
@Async
public class AsyncTask {

    public void task1() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(3000);
        long end = System.currentTimeMillis();
        System.out.println("当前线程:" + Thread.currentThread().getName() + "," + "任务一耗时:" + (end - start) + "ms");
    }

    public void task2() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(3000);
        long end = System.currentTimeMillis();
        System.out.println("当前线程:" + Thread.currentThread().getName()  + "," + "任务二耗时:" + (end - start) + "ms");
    }

    public void task3() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(3000);
        long end = System.currentTimeMillis();
        System.out.println("当前线程:" + Thread.currentThread().getName() + "," + "任务三耗时:" + (end - start) + "ms");
    }

调用异步任务

package com.ming.asyncservice;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TaskService {

    @Autowired
    private AsyncTask asyncTask;

    @RequestMapping("/taskService")
    public String doTask() throws InterruptedException {

        long start = System.currentTimeMillis();
        asyncTask.task1();
        asyncTask.task2();
        asyncTask.task3();
        long end = System.currentTimeMillis();
        System.out.println("任务总耗时:" + (end - start) + "ms");
        return "任务总耗时:" + (end - start) + "ms";
    }
}

开启异步任务

package com.ming;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@SpringBootApplication
public class ScheduleTaskApplication {

    public static void main(String[] args) {
    
        SpringApplication.run(ScheduleTaskApplication.class, args);
    }

测试结果

默认异步任务线程池

   SpringBoot异步任务默认使用的线程池为SimpleAsyncTaskExecutor,其特点如下:

  • 默认定义多少异步任务,创建多少线程(创建线程数量太多,占用内存过大,会造成OutOfMemoryError)。
  • SimpleAsyncTaskExecutor不提供拒绝策略机制。
  • SimpleAsyncTaskExecutor可通过设置参数concurrencyLimit(值为大于或等于0的整数),指定启用的线程数目;默认concurrencyLimit取值为-1,即不启用资源节流。

自定义异步任务线程池

package com.ming.asyncservice;

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;

@Configuration
public class AsyncThreadPoolConfig implements AsyncConfigurer {
	
	/**
     * 自定义线程池
     * @return 线程池对象
     */
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(5);
        threadPoolTaskExecutor.setMaxPoolSize(8);
        threadPoolTaskExecutor.setQueueCapacity(10);
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
	
	/**
     * 自定义异常处理器
     * @return 异常处理器对象
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        AsyncUncaughtExceptionHandler syncUncaughtExceptionHandler = (ex, method, params) -> ex.printStackTrace();
        return syncUncaughtExceptionHandler;
    }
}

测试结果

  获取异步任务对应的线程名称,线程池从默认的SimpleAsyncTaskExecutor转换成自定义的ThreadPoolTaskExecutor。

猜你喜欢

转载自blog.csdn.net/Mr_FLM/article/details/92780963
今日推荐