宜昌网站建设平台,wordpress外贸建站 视频教程,网络游戏推广怎么做,只有网站才需要域名吗还在用 for 循环计算两个数之间所有数的和吗#xff1f;下面提供两种新方法#xff01;
1. ForkJoin
1.1 背景
要知道#xff0c;在一个方法中#xff0c;如果没有做特殊的处理#xff0c;那么在方法开始到结束使用的都是同一个线程#xff0c;无论你的业务有多复杂 那…还在用 for 循环计算两个数之间所有数的和吗下面提供两种新方法
1. ForkJoin
1.1 背景
要知道在一个方法中如果没有做特殊的处理那么在方法开始到结束使用的都是同一个线程无论你的业务有多复杂 那么就有人在想能不能在一个方法里使用多个线程来完成一个复杂的业务
ForkJoin 拆分合并 在一定程度上满足了上述的场景使用 ForkJoin 后可以根据自己的需要将一个任务拆分为多个任务当多个任务都执行完后再将结果汇总返回
1.2 实例
比如我现在要计算 11000000000 之间所有数的和
继承 RecursiveTask 并行任务类编写对应的计算方法
public class ForkJoinDemo extends RecursiveTaskLong {private Long start;private Long end;private Long temp 1000L; // 临界值public ForkJoinDemo(Long start, Long end) {this.start start;this.end end;}Overrideprotected Long compute() {if ((end - start) temp) {// 数据量不大就不必拆分任务Long sum 0L;for (Long i start; i end; i) {sum i;}return sum;} else {long middle (start end) 1; // 中间值ForkJoinDemo task1 new ForkJoinDemo(start, middle);task1.fork(); // 拆分任务把任务压入队列ForkJoinDemo task2 new ForkJoinDemo(middle1, end);task2.fork(); // 拆分任务把任务压入队列// 合并结果return task1.join() task2.join();}}
}编写测试类调用上面的方法
public class DemoTest01 {public static void main(String[] args) throws Exception {ForkJoinPool forkJoinPool new ForkJoinPool();ForkJoinTaskLong task new ForkJoinDemo(0L, 10_0000_0000L);ForkJoinTaskLong submit forkJoinPool.submit(task);Long sum submit.get();System.out.println(sum sum);}
}1.3 注意点
细心的人应该会看到本人在计算中间值时使用了位运算 并不是因为显得很厉害而是因为之前踩过坑
细想如果是 int 类型的话(start end) / 2 乍一眼看上去好像没什么问题 但我们都知道 int 的最大值是 2147483647。如果 start 2147483645end 2147483645虽然 start 和 end 都没有超出最大值但是如果加起来的话就会造成溢出从而导致中间值计算错误
所以也是提醒大家越是简单的问题越容易被忽略
2. Stream 并行流
如何使用 Stream 并行流实现计算 11000000000 之间所有数的和 一行代码解决
public class DemoTest01 {public static void main(String[] args) throws Exception {// rangeClosed 前开后闭 (]long sum LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0, Long::sum);System.out.println(sum sum);}
}