常用的几种异步场景实现方式

111 阅读2分钟

前提:

在不考虑公司自己的异步任务工具类,自定义异步注解这些,只考虑通用的实现方式,包括一些开源的第三方jar包实现

以下都是一些自己常用的实现方式

不需要异步任务结果的情况下:

1.如果实现场景简单,并发不高,可以考虑使用juc包下的Executors

  • Executors.newSingleThreadExecutor() 创建只有一个线程的线程池
  • Executors.newFixedThreadPool(int nThreads) 创建具有指定数量线程数的线程池
  • Executors.newCachedThreadPool() 创建一个线程池,线程池中的线程空闲时间超过60秒就销毁线程
  • Executors.newScheduledThreadPool(2) 创建有定时功能的线程池

举一个简单使用例子

    public static void main(String[] args) throws Exception{
        // 创建线程池
        ExecutorService es = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 5; i++) {
            es.execute(() -> {
            //此处实现异步逻辑
                System.out.println(Thread.currentThread().getName()+" 线程运行");
            });
        }
        // 关闭线程池
        es.shutdown();

2.如果考虑对线程池有要求,并且有一定的复用性,可以考虑使用spring下的Async注解+ThreadPoolTaskExecutor类去使用

Async注解可以使被修饰的方法成为异步方法,并且可以配置自定义的线程池使用,如果不配置默认使用的spring的无边界线程池,当执行被Async修饰的方法时,会调用配置的线程池异步执行。而ThreadPoolTaskExecutor是spring自带的线程池,可以理解为是对ThreadPoolExecutor的再封装。

举一个简单使用例子

TheadPoolTaskExecutor配置类

@Configuration
@Slf4j
public class ExecutorConfig {
 
    @Value("${async.executor.thread.core_pool_size}")
    private int corePoolSize;
    @Value("${async.executor.thread.max_pool_size}")
    private int maxPoolSize;
    @Value("${async.executor.thread.queue_capacity}")
    private int queueCapacity;
    @Value("${async.executor.thread.name.prefix}")
    private String namePrefix;
    @Value("${async.executor.thread.keep_alive_seconds}")
    private int keepAliveSeconds;
 
    @Bean(name = "asyncTaskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        log.info("启动");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数
        executor.setCorePoolSize(corePoolSize);
        // 最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        // 任务队列大小
        executor.setQueueCapacity(queueCapacity);
        // 线程前缀名
        executor.setThreadNamePrefix(namePrefix);
        // 线程的空闲时间
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 线程初始化
        executor.initialize();
        return executor;
    }
}

异步场景实现类

@Component
@Slf4j
public class ThreadTest {
    
    @Async("asyncTaskExecutor")
    public void ceshi() {
        //此处实现异步逻辑
                System.out.println(Thread.currentThread().getName()+" 线程运行");
    }

测试类

// 在启动类上添加 @EnableScheduling 注解
@SpringBootApplication
@EnableScheduling
public class SpringBootStudyApplication {
   public static void main(String[] args) {
      SpringApplication.run(SpringBootStudyApplication.class, args);
   }
}

@Component
public class listennerTest3 {
 
    @Autowired
    private ThreadTest t;
 
    
    public void run() {
        t.ceshi();
    }
}

需要异步任务结果的情况下:

可以使用CompletableFuture,注意获取结果的同时是同步阻塞的

具体使用参考:blog.csdn.net/zsx_xiaoxin…