java 代码异步执行_Java实现异步调用

布满荆棘的人生 2023-10-02 16:42 33阅读 0赞

一、创建线程

  1. @Test
  2. public void test0() throws Exception {
  3. System.out.println("main函数开始执行");
  4. Thread thread =
  5. new Thread(
  6. new Runnable() {
  7. @Override
  8. public void run() {
  9. System.out.println("===task start===");
  10. try {
  11. Thread.sleep(300);
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. System.out.println("===task finish===");
  16. }
  17. });
  18. thread.start();
  19. System.out.println("main函数执行结束");
  20. }
  21. 二、Future
  22. jdk8之前的实现方式,在JUC下增加了Future,从字面意思理解就是未来的意思,但使用起来却着实有点鸡肋,并不能实现真正意义上的异步,获取结果时需要阻塞线程,或者不断轮询。
  23. @Test
  24. public void test1() throws Exception {
  25. System.out.println("main函数开始执行");
  26. ExecutorService executor = Executors.newFixedThreadPool(1);
  27. Future future =
  28. executor.submit(
  29. new Callable() {
  30. @Override
  31. public Integer call() throws Exception {
  32. System.out.println("===task start===");
  33. Thread.sleep(5000);
  34. System.out.println("===task finish===");
  35. return 3;
  36. }
  37. });
  38. // 这里需要返回值时会阻塞主线程,如果不需要返回值使用是OK的。倒也还能接收
  39. //Integer result=future.get();
  40. System.out.println("main函数执行结束");
  41. System.in.read();
  42. }

三、CompletableFuture

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

  1. // 两个线程的线程池
  2. ExecutorService executor = Executors.newFixedThreadPool(2);
  3. // jdk1.8之前的实现方式
  4. CompletableFuture<String> future =
  5. CompletableFuture.supplyAsync(
  6. new Supplier<String>() {
  7. @Override
  8. public String get() {
  9. System.out.println("开始执行任务!");
  10. try {
  11. // 模拟耗时操作
  12. Thread.sleep(20000);
  13. System.out.println("我是一个特别耗时的任务");
  14. } catch (Exception e) {
  15. e.printStackTrace();
  16. }
  17. return "耗时任务结束完毕!";
  18. }
  19. },
  20. executor);
  21. // 采用lambada的实现方式
  22. future.thenAccept(e -> System.out.println(e + " ok"));
  23. System.out.println("不等上面了,我先跑了"); //

四、Spring的Async注解

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

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

发表评论

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

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

相关阅读