Я пытаюсь разделить очень дорогой расчет на несколько меньших вычислений, чтобы выполнить их через ExecutorService (если имеется).
Поэтому я решил создать несколько Callables, которые выполняют определенную частьвесь расчет.Некоторые расчеты зависят от предыдущего результата, другие - нет.
Кроме того, я добавил метод, который решает, как выполнить каждый из вызываемых элементов
private <T> Supplier<T> executeCalculation(Callable<T> callable) {
if (executorService != null) {
Future<T> future = executorService.submit(callable);
return () -> {
try {
return future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
throw new RuntimeException();
};
} else {
return () -> {
try {
return callable.call();
} catch (Exception e) {
e.printStackTrace();
}
throw new RuntimeException();
};
}
}
Этот метод вызывается несколько раз из другого метода, который разбивает вычисления на более мелкие части.
Таким образом, при выполнении вычисления с использованием VisualVM вы можете четко видеть, что ни один поток не выполняет ничего, но вся работа выполняется потоком GUI.
Дополнительная информация: Используемая мной служба ExecutorService Executors.newCachedThreadPool();
Методвызов метода createCalculation
выглядит следующим образом:
public BigDecimal chudnovskyNumber(int k, MathContext context) {
Callable<BigDecimal> f1 = () -> factorial(6 * k);
Callable<BigDecimal> f2 = () -> factorial(3 * k);
Callable<BigDecimal> f3 = () -> factorial(k);
Callable<BigDecimal> mul1 = () -> BigDecimal.valueOf(545140134).multiply(BigDecimal.valueOf(k));
Callable<BigDecimal> pow1 = () -> BigDecimal.valueOf(-262537412640768000L).pow(k);
Supplier<BigDecimal> f1Supplier = executeCalculation(f1);
Supplier<BigDecimal> f2Supplier = executeCalculation(f2);
Supplier<BigDecimal> f3Supplier = executeCalculation(f3);
Supplier<BigDecimal> m1Supplier = executeCalculation(mul1);
Supplier<BigDecimal> pow1Supplier = executeCalculation(pow1);
Callable<BigDecimal> m2 = () -> f1Supplier.get().multiply(m1Supplier.get());
Callable<BigDecimal> pow2 = () -> f3Supplier.get().pow(3);
Supplier<BigDecimal> m2Supplier = executeCalculation(m2);
Supplier<BigDecimal> pow2Supplier = executeCalculation(pow2);
Callable<BigDecimal> addition1 = () -> m2Supplier.get().add(BigDecimal.valueOf(13591409));
Callable<BigDecimal> m3 = () -> f2Supplier.get().multiply(pow2Supplier.get());
Supplier<BigDecimal> addition1Supplier = executeCalculation(addition1);
Supplier<BigDecimal> m3Supplier = executeCalculation(m3);
Callable<BigDecimal> m4 = () -> m3Supplier.get().multiply(pow1Supplier.get());
Supplier<BigDecimal> m4Supplier = executeCalculation(m4);
Supplier<BigDecimal> resultSupplier = () -> addition1Supplier.get().divide(m4Supplier.get(), context).stripTrailingZeros();
return resultSupplier.get();
}