本文共 5706 字,大约阅读时间需要 19 分钟。
@EnableAsync:通过在配置类或者Main类上加@EnableAsync开启对异步方法的支持。
@Async 可以作用在类上或者方法上,作用在类上代表这个类的所有方法都是异步方法。
创建一个异步的任务配置类
package com.xiaobu.config;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;/** * @author xiaobu * @version JDK1.8.0_171 * @date on 2019/10/10 16:38 * @description 异步任务配置类 */@Configuration@EnableAsyncpublic class AsyncConfig { private static final int CORE_POOL_SIZE = 6; private static final int MAX_POOL_SIZE = 10; private static final int QUEUE_CAPACITY = 100; @Bean public Executor taskExecutor() { ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); threadPoolTaskExecutor.setCorePoolSize(CORE_POOL_SIZE); threadPoolTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE); threadPoolTaskExecutor.setQueueCapacity(QUEUE_CAPACITY); // 当最大池已满时,此策略保证不会丢失任务请求,但是可能会影响应用程序整体性能。 threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); threadPoolTaskExecutor.setThreadNamePrefix("My ThreadPoolTaskExecutor-"); threadPoolTaskExecutor.initialize(); return threadPoolTaskExecutor; }}
CompletableFuture.completedFuture(results) 完成之后再返回结果
package com.xiaobu.service;import com.xiaobu.mapper.AreaMapper;import lombok.extern.slf4j.Slf4j;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.Arrays;import java.util.List;import java.util.concurrent.CompletableFuture;import java.util.concurrent.TimeUnit;import java.util.stream.Collectors;/** * @author xiaobu * @version JDK1.8.0_171 * @date on 2019/10/10 * @description V1.0 */@Service@Slf4jpublic class AsyncService { private Listmovies = Arrays.asList("AAA", "BBB", "CCC", "DDD", "EEE", "FFF"); @Async public CompletableFuture
> ompletableFutureTask(String start){ log.info("[{}] start task",Thread.currentThread().getName()); List result=movies.stream().filter(movie->movie.startsWith(start)).collect(Collectors.toList()); try { //模拟执行时间 TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } //返回一个已经用给定值完成的新的CompletableFuture。 return CompletableFuture.completedFuture(result); } public static void main(String[] args) { AsyncService service = new AsyncService(); service.ompletableFutureTask("A"); List words = Arrays.asList("A", "B"); List
>> completableFutureList = words.stream().map(service::ompletableFutureTask).collect(Collectors.toList()); System.out.println("completableFutureList = " + completableFutureList); }}
编写异步方法
package com.xiaobu.controller;import com.xiaobu.base.utils.CmdUtils;import com.xiaobu.service.AsyncService;import org.springframework.util.StopWatch;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;import java.util.Arrays;import java.util.List;import java.util.concurrent.CompletableFuture;import java.util.concurrent.TimeUnit;import java.util.stream.Collectors;/** * @author xiaobu * @version JDK1.8.0_171 * @date on 2019/8/23 13:40 * @description */@RestController@RequestMapping("async")public class AsyncController { @Resource private AsyncService asyncService; @GetMapping("movie") public String movies() { long startTime = System.currentTimeMillis(); StopWatch stopWatch = new StopWatch(); stopWatch.start("movie任务"); Listwords = Arrays.asList("A", "B","C","D","E","F"); List
>> completableFutureList = words.stream().map(word -> asyncService.ompletableFutureTask(word)).collect(Collectors.toList()); List
> results = completableFutureList.stream().map(CompletableFuture::join).collect(Collectors.toList()); stopWatch.stop(); System.out.println("stopWatch = " + stopWatch.prettyPrint()); System.out.println("耗时:"+(System.currentTimeMillis() - startTime)); return results.toString(); }}
结果如下:
可以看出执行任务花费了1秒钟的时间,6个线程异步执行的。下面将核心线程池大小改成2之后,查看下执行结果。
改造下service和controller类 业务层设置无返回值
@Async public void ompletableFutureTask(String start){ log.info("[{}] start task",Thread.currentThread().getName()); Listresult=movies.stream().filter(movie->movie.startsWith(start)).collect(Collectors.toList()); try { //模拟执行时间 TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } //返回一个已经用给定值完成的新的CompletableFuture。 System.out.println("result = " + result); }
@GetMapping("movie") public String movies() { long startTime = System.currentTimeMillis(); StopWatch stopWatch = new StopWatch(); stopWatch.start("movie任务"); Listwords = Arrays.asList("A", "B","C","D","E","F"); words.stream().forEach(word -> asyncService.ompletableFutureTask(word)); stopWatch.stop(); System.out.println("stopWatch = " + stopWatch.prettyPrint()); System.out.println("耗时:"+(System.currentTimeMillis() - startTime)); return "success"; }
结果:先返回结果,然后系统再执行。
转载地址:http://rgrai.baihongyu.com/