I am trying to calculate some big numbers. To speed up the calculation, I would like to use multithreading. Each thread must calculate a number, and at the end the sum is calculated.
I once saw something that worked with SumThread and Collector , which looked like this:
public BigInteger compute(int p) { Collector c = new Collector(p); for(T element : Collection<T> bigCollection) { new SumThread(c) { @Override protected void doTheJob() { long big = someVeryComplexCalculation(element, ...); //n! receive(BigInteger.valueOf(big)); } } } if(collector.isReady()) return collector.getResult(); return null; } public class Collector { private int numberOfProcesses; private int numberOfAllowedProcesses; private BigInteger result; public Collector(int n) { numberOfAllowedProcesses = n; numberOfProcesses = 0; result = BigInteger.ZERO; } synchronized public void enter() throws InterruptedException { if (numberOfProcesses == numberOfAllowedProcesses) wait(); numberOfProcesses++; } synchronized public void leave() { numberOfProcesses--; notify(); } synchronized public void register(BigInteger v) { result = result.add(v); } synchronized public boolean isReady() throws InterruptedException { while (numberOfProcesses > 0) wait(); return true; } ... } public abstract class SumThread extends Thread { private Collector collector; public SumThread(Collector c) throws InterruptedException { collector = c; collector.enter(); } abstract protected void doTheJob(); //complex calculations can be done in here public void receive(BigInteger t) { collector.register(t); } public void run() { doTheJob(); collector.leave(); } }
I thought I could easily surpass this by using ExecutorService instead of constantly adding a new Thread :
public BigInteger compute(int p) { ExecutorService pool = Executors.newFixedThreadPool(p); Future<BigInteger>[] futures = new Future<BigInteger>[bigCollection.size()]; int i = 0; for(T element : Collection<T> bigCollection) { futures[i++] = p.submit(new Callable<BigInteger>() { @Override public BigInteger call() { long big = someVeryComplexCalculation(element, ...);
However, this code could not surpass the SumThread - Collector solution. I also saw things about LongAdder , for example, but I need some kind of adder for BigInteger s ...
So my question is: how can I calculate the amount at the same time? Is this one of the above or is there a completely different (but better) way?
source share