让知识连接你我
投稿赚钱
当前位置: 首页 > 后端开发 > 教你如何用 Java 实现异步调用
  • 101
  • 微信分享

    扫一扫,在手机上查看

教你如何用 Java 实现异步调用

2019.01.10 10:00 281 浏览 举报

  本实例教程手把手教你应用Java完成异步调用。

  一、构建线程

  @Test
  public void test0() throws Exception {
  System.out.println("main函数开始执行");
  Thread thread=new Thread(new Runnable() {
  @Override
  public void run() {
  System.out.println("===task start===");
  try {
  Thread.sleep(5000);
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
  System.out.println("===task finish===");
  }
  });
  thread.start();
  System.out.println("main函数执行结束");
  }

  二、Future

  jdk8之前的完成形式,在JUC下提升了Future,从字面上意思掌握便是未来的意思,但应用起来却着实有些鸡肋,并不能完成真实意义上的异步,获得结果时必须阻塞线程,或者持续轮询。

  @Test
  public void test1() throws Exception {
  System.out.println("main函数开始执行");
  ExecutorService executor = Executors.newFixedThreadPool(1);
  Future<Integer> future = executor.submit(new Callable<Integer>() {
  @Override
  public Integer call() throws Exception {
  System.out.println("===task start===");
  Thread.sleep(5000);
  System.out.println("===task finish===");
  return 3;
  }
  });
  //这里需要返回值时会阻塞主线程,如果不需要返回值使用是OK的。倒也还能接收
  //Integer result=future.get();
  System.out.println("main函数执行结束");
  System.in.read();
  }

  三、CompletableFuture

  使用原生的CompletableFuture实现异步操作,加上对lambda的支持,可以说实现异步任务已经发挥到了极致。

  @Test
  public void test2() throws Exception {
  System.out.println("main函数开始执行");
  ExecutorService executor = Executors.newFixedThreadPool(2);
  CompletableFuture<Integer> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
  @Override
  public Integer get() {
  System.out.println("===task start===");
  try {
  Thread.sleep(5000);
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
  System.out.println("===task finish===");
  return 3;
  }
  }, executor);
  future.thenAccept(e -> System.out.println(e));
  System.out.println("main函数执行结束");
  }

  四、Spring的Async注解

  应用spring完成异步必须开启注解,可以应用xml形式或者Java config的形式。

  xml形式:

  <task:annotation-driven executor="executor" />
  <task:executor id="executor"
  pool-size="2" 线程池的大小
  queue-capacity="100" 排队队列长度
  keep-alive="120" 线程保活时间(单位秒)
  rejection-policy="CALLER_RUNS" 对拒绝的任务处理策略 />

  java形式:

  @EnableAsync
  public class MyConfig {
  @Bean
  public TaskExecutor executor(){
  ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
  executor.setCorePoolSize(10); //核心线程数
  executor.setMaxPoolSize(20);  //最大线程数
  executor.setQueueCapacity(1000); //队列大小
  executor.setKeepAliveSeconds(300); //线程最大空闲时间
  executor.setThreadNamePrefix("fsx-Executor-"); //指定用于新创建的线程名称的前缀。
  executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  return executor;
  }
  }

  (1)@Async

  @Test
  public void test3() throws Exception {
  System.out.println("main函数开始执行");
  myService.longtime();
  System.out.println("main函数执行结束");
  }
  @Async
  public void longtime() {
  System.out.println("我在执行一项耗时任务");
  try {
  Thread.sleep(5000);
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
  System.out.println("完成");
  }

  (2)AsyncResult

  如果必须返回值,耗时形式返回值用AsyncResult包装。

  @Test
  public void test4() throws Exception {
  System.out.println("main函数开始执行");
  Future future=myService.longtime2();
  System.out.println("main函数执行结束");
  System.out.println("异步执行结果:"+future.get());
  }
  @Async
  public Future longtime2() {
  System.out.println("我在执行一项耗时任务");
  try {
  Thread.sleep(8000);
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
  System.out.println("完成");
  return new AsyncResult<>(3);
  }


本文首次发布于开创者素材 ,转载请注明出处,谢谢合作!

相关文章推荐