import java.math.BigInteger;
import java.util.concurrent.*;
public class MyFactorialSum {
public static void main(String[] args) throws InterruptedException {
long startTime, endTime;
// 顺序计算表示结果
BigInteger sum1 = BigInteger.ZERO;
// 并行计算表示结果
final BigInteger[] sum2 = {BigInteger.ZERO};
// 阶乘起始值和结束值
int num1 = 1;
int num2 = 100;
//子任务数
int taskNum = 10;
// 顺序计算:
startTime = System.currentTimeMillis();
sum1 = calculationSum(num1, num2);
endTime = System.currentTimeMillis();
System.out.println("顺序计算的数是:"+sum1+"\n所需的时间是:"+(endTime-startTime)+ "s");
// 并行计算:
// 执行线程池
ExecutorService executor = Executors.newFixedThreadPool(taskNum);
// 开始计时
startTime = System.currentTimeMillis();
for (int i = 0; i < taskNum; i++) {
int finalI = i;
// 可以先创建匿名内部类再转成lambada表达式
executor.submit(() -> {
BigInteger bigInteger = calculationSum(10 * finalI + 1, 10 * (finalI + 1));
synchronized (sum2[0]) {
sum2[0] = sum2[0].add(bigInteger);
}
});
}
// awaitTermination一般和shutdown结合使用
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
// 结束计时
endTime = System.currentTimeMillis();
System.out.println("并行计算的数是:"+ sum2[0] +"\n所需的时间是:"+(endTime-startTime)+ "s");
}
// 计算每个数的阶乘
private static BigInteger calculationFactorial(int n){
BigInteger result = BigInteger.ONE;
for (int i = 1; i <= n; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
// 计算所有数的阶乘和
private static BigInteger calculationSum(int start, int end){
BigInteger sum = BigInteger.ZERO;
for (int i = start; i <= end; i++) {
sum = sum.add(calculationFactorial(i));
}
return sum;
}
}
此题所计算的数特别大,甚至超过了long类型,在java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,有一个缺点就是比较费内存,同时BigInteger还提供了一些方法和常量。