• FutureTask和CompletableFuture的模拟使用


     模拟了查询耗时操作,并使用FutureTask和CompletableFuture分别获取计算结果,统计执行时长

    1. package org.alllearn.futurtask;
    2. import com.google.common.base.Stopwatch;
    3. import com.google.common.collect.Lists;
    4. import lombok.AllArgsConstructor;
    5. import lombok.Getter;
    6. import lombok.Setter;
    7. import java.util.ArrayList;
    8. import java.util.List;
    9. import java.util.concurrent.CompletableFuture;
    10. import java.util.concurrent.ExecutionException;
    11. import java.util.concurrent.ForkJoinPool;
    12. import java.util.concurrent.FutureTask;
    13. import java.util.stream.Collectors;
    14. public class CompletableFutureTest {
    15. public static void main(String[] args) {
    16. CompletableFutureTest test = new CompletableFutureTest();
    17. List users = test.getUsers();
    18. //流计算的简单使用
    19. Stopwatch started = Stopwatch.createStarted();
    20. double average = users.stream().mapToInt(User::getAge).average().getAsDouble();
    21. System.out.println(average + " " + started.elapsed());
    22. //模拟通过id集合去其他表批量查询数据
    23. //单线程任务分割,数据库承受不了大量id的in查询
    24. List> partition1 = Lists.partition(users, users.size() / 200);
    25. started.reset();
    26. started.start();
    27. double average1 = partition1.stream().mapToDouble(test::select).average().getAsDouble();
    28. System.out.println(average1 + " " + started.elapsed());
    29. //多线程任务两种方案FutureTask、CompletableFuture
    30. int cpu = Runtime.getRuntime().availableProcessors();
    31. //计算密集型cpu+1,io密集型cpu*2
    32. ForkJoinPool forkJoinPool = new ForkJoinPool(cpu + 1);
    33. List> partition2 = Lists.partition(users, users.size() / 200);
    34. //FutureTask
    35. started.reset();
    36. started.start();
    37. double average2 = partition2.stream()
    38. .map(u -> {
    39. FutureTask futureTask = new FutureTask<>(() -> test.select(u));
    40. forkJoinPool.submit(futureTask);
    41. return futureTask;
    42. })
    43. .collect(Collectors.toList())
    44. .stream().
    45. mapToDouble(f -> {
    46. try {
    47. return f.get();
    48. } catch (InterruptedException | ExecutionException e) {
    49. throw new RuntimeException(e);
    50. }
    51. })
    52. .average()
    53. .getAsDouble();
    54. System.out.println(average2 + " " + started.elapsed());
    55. //CompletableFuture
    56. started.reset();
    57. started.start();
    58. double average3 = partition2.stream()
    59. .map(u -> CompletableFuture.supplyAsync(() -> test.select(u), forkJoinPool))
    60. .collect(Collectors.toList())
    61. .stream().
    62. mapToDouble(CompletableFuture::join)
    63. .average()
    64. .getAsDouble();
    65. forkJoinPool.shutdown();
    66. System.out.println(average3 + " " + started.elapsed());
    67. }
    68. //模拟查询耗时
    69. public Double select(List user) {
    70. try {
    71. Thread.sleep(100);
    72. } catch (InterruptedException e) {
    73. throw new RuntimeException(e);
    74. }
    75. return 1D;
    76. //return Math.random();
    77. }
    78. //模拟获取用户
    79. public List getUsers() {
    80. List users = new ArrayList<>();
    81. for (int i = 0; i < 20000; i++) {
    82. users.add(new User(i, "user" + i, 1));
    83. }
    84. return users;
    85. }
    86. @Getter
    87. @Setter
    88. @AllArgsConstructor
    89. static class User {
    90. private int id;
    91. private String name;
    92. private int age;
    93. }
    94. }

    运行结果

  • 相关阅读:
    【计算机毕业设计】小型OA系统设计与实现Springboot
    Alook获取站点cookie详细教程
    C练习题_13
    【计算机网络】应用层——HTTPS协议
    Qt QSVG使用详解
    台式机电脑电源的使用
    pip修改位于用户目录下的缓存目录
    让陪伴机器人不再「直男」,读懂更多情绪 | 香港理工大学李嫣然
    go语言中的数组指针和指针数组的区别详解
    Node.js躬行记(28)——Cypress自动化测试实践
  • 原文地址:https://blog.csdn.net/z275598733/article/details/133710581