当前位置: 主页 > JAVA语言

java多线程异步并行-java起异步线程

发布时间:2023-02-09 16:18   浏览次数:次   作者:佚名

深入理解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();
  }

java起异步线程_java多线程异步并行_同步 异步 并行 并发

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

java起异步线程_java多线程异步并行_同步 异步 并行 并发

AsyncExecutorThread-1 deal No Return Task end at 1499751227034

从日志中可以看出java多线程异步并行,dealNoReturnTask()方法是异步执行的。

dealNoReturnTask() 设置sleep 3s 模拟耗时任务

testDealNoReturnTask() 设置sleep 10s 确认异步执行是否完成

4.@Async返回数据

异步调用返回数据,Future表示获取未来某个时间点的执行结果,返回数据类型可自定义

 @Async
 public Future dealHaveReturnTask() {
  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 {
  Future future = asyncTask.dealHaveReturnTask();
  log.info("begin to deal other Task!");
  while (true) {

java起异步线程_同步 异步 并行 并发_java多线程异步并行

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 是使用 threadPoolTask​​Executor() 定义的,则不需要初始化

java多线程异步并行_同步 异步 并行 并发_java起异步线程

@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();

java多线程异步并行_java起异步线程_同步 异步 并行 并发

} }

异步异常处理类:

@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 的支持。