Java 实现异步调用

以你之姓@ 2023-06-30 04:28 99阅读 0赞

一、创建线程

  1. @Test
  2. public void test0() throws Exception {
  3. System.out.println("main函数开始执行");
  4. Thread thread=new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. System.out.println("===task start===");
  8. try {
  9. Thread.sleep(5000);
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. System.out.println("===task finish===");
  14. }
  15. });
  16. thread.start();
  17. System.out.println("main函数执行结束");
  18. }

二、Future
jdk8之前的实现方式,在JUC下增加了Future,从字面意思理解就是未来的意思,但使用起来却着实有点鸡肋,并不能实现真正意义上的异步,获取结果时需要阻塞线程,或者不断轮询。

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

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

  1. @Test
  2. public void test2() throws Exception {
  3. System.out.println("main函数开始执行");
  4. ExecutorService executor = Executors.newFixedThreadPool(2);
  5. CompletableFuture<Integer> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
  6. @Override
  7. public Integer get() {
  8. System.out.println("===task start===");
  9. try {
  10. Thread.sleep(5000);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. System.out.println("===task finish===");
  15. return 3;
  16. }
  17. }, executor);
  18. future.thenAccept(e -> System.out.println(e));
  19. System.out.println("main函数执行结束");
  20. }

四、Spring的Async注解
使用spring实现异步需要开启注解,可以使用xml方式或者Java config的方式。

  1. xml方式:
  2. <task:annotation-driven executor="executor" />
  3. <task:executor id="executor"
  4. pool-size="2" 线程池的大小
  5. queue-capacity="100" 排队队列长度
  6. keep-alive="120" 线程保活时间(单位秒)
  7. rejection-policy="CALLER_RUNS" 对拒绝的任务处理策略 />
  8. java方式:
  9. @EnableAsync
  10. public class MyConfig {
  11. @Bean
  12. public TaskExecutor executor(){
  13. ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
  14. executor.setCorePoolSize(10); //核心线程数
  15. executor.setMaxPoolSize(20); //最大线程数
  16. executor.setQueueCapacity(1000); //队列大小
  17. executor.setKeepAliveSeconds(300); //线程最大空闲时间
  18. executor.setThreadNamePrefix("fsx-Executor-"); //指定用于新创建的线程名称的前缀。
  19. executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  20. return executor;
  21. }
  22. }
  23. 1@Async
  24. @Test
  25. public void test3() throws Exception {
  26. System.out.println("main函数开始执行");
  27. myService.longtime();
  28. System.out.println("main函数执行结束");
  29. }
  30. @Async
  31. public void longtime() {
  32. System.out.println("我在执行一项耗时任务");
  33. try {
  34. Thread.sleep(5000);
  35. } catch (InterruptedException e) {
  36. e.printStackTrace();
  37. }
  38. System.out.println("完成");
  39. }
  40. 2AsyncResult
  41. 如果需要返回值,耗时方法返回值用AsyncResult包装。
  42. @Test
  43. public void test4() throws Exception {
  44. System.out.println("main函数开始执行");
  45. Future future=myService.longtime2();
  46. System.out.println("main函数执行结束");
  47. System.out.println("异步执行结果:"+future.get());
  48. }
  49. @Async
  50. public Future longtime2() {
  51. System.out.println("我在执行一项耗时任务");
  52. try {
  53. Thread.sleep(8000);
  54. } catch (InterruptedException e) {
  55. e.printStackTrace();
  56. }
  57. System.out.println("完成");
  58. return new AsyncResult<>(3);
  59. }

发表评论

表情:
评论列表 (有 0 条评论,99人围观)

还没有评论,来说两句吧...

相关阅读