java多线程异步并行-java起异步线程
深入理解spring boot异步调用方法@Async
更新时间:2017-07-13 09:42:42 作者:沉淀
Spring为任务调度和异步方法执行提供注解支持。 通过在方法上设置@Async 注解,可以异步调用该方法。 下面这篇文章主要介绍spring boot异步调用方法@Async的相关信息。 需要的朋友可以参考一下。
本文主要介绍了spring boot异步调用方法@Async的相关内容,分享给大家参考学习。 我们来看看详细的介绍:
1.使用背景
在日常开发项目中,当访问别人的界面比较慢或者做耗时任务时,我们不希望程序一直卡在耗时任务上,而是希望程序能够并行执行。 我们可以使用多线程并行处理任务,也可以使用spring提供的异步处理方法@Async。
2.异步处理方式
3.@Async不返回数据
使用@EnableAsync 启用异步注解
@Configuration @EnableAsync @Slf4j public class AsyncConfig{ }
在异步处理方法dealNoReturnTask上添加注解@Async
@Component @Slf4j public class AsyncTask { @Async public void dealNoReturnTask(){ log.info("Thread {} deal No Return Task start", Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } log.info("Thread {} deal No Return Task end at {}", Thread.currentThread().getName(), System.currentTimeMillis()); } }
测试测试类:
@SpringBootTest(classes = SpringbootApplication.class) @RunWith(SpringJUnit4ClassRunner.class) @Slf4j public class AsyncTest { @Autowired private AsyncTask asyncTask; @Test public void testDealNoReturnTask(){ asyncTask.dealNoReturnTask(); try { log.info("begin to deal other Task!"); Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } }
日志打印结果为:
begin to deal other Task! AsyncExecutorThread-1 deal No Return Task start AsyncExecutorThread-1 deal No Return Task end at 1499751227034
从日志中可以看出java多线程异步并行,dealNoReturnTask()方法是异步执行的。
dealNoReturnTask() 设置sleep 3s 模拟耗时任务
testDealNoReturnTask() 设置sleep 10s 确认异步执行是否完成
4.@Async返回数据
异步调用返回数据,Future表示获取未来某个时间点的执行结果,返回数据类型可自定义
@Async public FuturedealHaveReturnTask() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } JSONObject jsonObject = new JSONObject(); jsonObject.put("thread", Thread.currentThread().getName()); jsonObject.put("time", System.currentTimeMillis()); return new AsyncResult (jsonObject.toJSONString()); }
测试类使用isCancelled判断异步任务是否取消,isDone判断任务执行是否完成
@Test public void testDealHaveReturnTask() throws Exception { Futurefuture = asyncTask.dealHaveReturnTask(); log.info("begin to deal other Task!"); while (true) { if(future.isCancelled()){ log.info("deal async task is Cancelled"); break; } if (future.isDone() ) { log.info("deal async task is Done"); log.info("return result is " + future.get()); break; } log.info("wait async task to end ..."); Thread.sleep(1000); } }
日志打印如下,我们可以看到任务一直在等待异步任务完成,使用future.get()获取异步任务的返回结果
begin to deal other Task! wait async task to end ... wait async task to end ... wait async task to end ... wait async task to end ... deal async task is Done return result is {"thread":"AsyncExecutorThread-1","time":1499752617330}
4.异常处理
我们可以实现AsyncConfigurer接口java多线程异步并行,或者继承AsyncConfigurerSupport类来实现
在方法getAsyncExecutor()中创建线程池时,必须使用executor.initialize(),否则调用时会报线程池未初始化的异常。
如果 bean 是使用 threadPoolTaskExecutor() 定义的,则不需要初始化
@Configuration @EnableAsync @Slf4j public class AsyncConfig implements AsyncConfigurer { // @Bean // public ThreadPoolTaskExecutor threadPoolTaskExecutor(){ // ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // executor.setCorePoolSize(10); // executor.setMaxPoolSize(100); // executor.setQueueCapacity(100); // return executor; // } @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(100); executor.setQueueCapacity(100); executor.setThreadNamePrefix("AsyncExecutorThread-"); executor.initialize(); //如果不初始化,导致找到不到执行器 return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new AsyncExceptionHandler(); } }
异步异常处理类:
@Slf4j public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler { @Override public void handleUncaughtException(Throwable ex, Method method, Object... params) { log.info("Async method: {} has uncaught exception,params:{}", method.getName(), JSON.toJSONString(params)); if (ex instanceof AsyncException) { AsyncException asyncException = (AsyncException) ex; log.info("asyncException:{}",asyncException.getErrorMessage()); } log.info("Exception :"); ex.printStackTrace(); } }
异步处理异常类:
@Data @AllArgsConstructor public class AsyncException extends Exception { private int code; private String errorMessage; }
总结
以上就是本文的全部内容。 希望本文的内容能为您的学习或工作带来一些帮助。 有什么问题可以留言交流。 感谢您对场景 3 的支持。