/* * numerical integration example, as discussed in textbook: * * compute pi by approximating the area under the curve f(x) = 4 / (1 + x*x) * between 0 and 1. * * parallel version using java.util.concurrent. */ package csci3366.sample.numint; import csci3366.sample.utility.Utility; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.ArrayList; public class NumIntPar2 { /* variables to be used by all threads */ private static long numSteps; private static double step; private static int numThreads; /* main method */ public static void main(String[] args) { /* process command-line arguments */ String usageMessage = "arguments: number_of_steps number_of_threads"; numSteps = Utility.getLongArg(args, 0, 1, "number_of_steps", usageMessage); numThreads = Utility.getIntegerArg(args, 1, 1, "number_of_threads", usageMessage); step = 1.0/(double) numSteps; double sum = 0.0; /* start timing */ long startTime = System.currentTimeMillis(); /* create executor for threads */ ExecutorService executor = Executors.newFixedThreadPool(numThreads); /* * create tasks that return partial sums and send to executor, * creating Future objects so we can wait for tasks to finish (and * get the returned values. * * see ArrayList here instead of array? see Hello5 example */ ArrayList> partialSums = new ArrayList>(); for (int i = 0; i < numThreads; ++i) { partialSums.add(executor.submit(new CodeForThread(i))); } /* shut down executor and wait for threads to finish */ executor.shutdown(); for (Future p : partialSums) { try { sum += p.get(); } catch (ExecutionException e) { System.err.println("should not happen"); } catch (InterruptedException e) { System.err.println("should not happen"); } } /* finish computation */ double pi = sum * step; /* end timing and print result */ long endTime = System.currentTimeMillis(); System.out.printf( "parallel program (v2) results with %d threads and %d steps\n", numThreads, numSteps); System.out.printf("computed pi = %17.15f\n" , pi); System.out.printf( "difference between estimated pi and Math.PI = %17.15f\n", Math.abs(pi - Math.PI)); System.out.printf("time to compute = %g seconds\n", (double) (endTime - startTime) / 1000); } /* static inner class to contain code to run in each thread */ private static class CodeForThread implements Callable { private int myID; public CodeForThread(int myID_) { myID = myID_; } public Double call() { double partsum = 0.0; for (int i=myID; i < numSteps; i += numThreads) { double x = (i+0.5)*step; partsum += 4.0/(1.0+x*x); } return new Double(partsum); } } }