import java.util.Arrays; public class SumThread extends Thread { private static double[] shared; private int id; private int startIndex, endIndex; private double sum; public SumThread(double[] data, int id, int i, int j) { this.id = id; startIndex = i; endIndex = j; shared = data; } public double getResult() { return sum; } public String toString() { return String.format("%02d: result=%.2f startIndex=%d", id, sum, startIndex); } public void run() { sum = 0; for (int i = startIndex; i <= endIndex; ++i) { sum += shared[i]; } System.out.println(toString()); //System.out.printf("id: %d, i=%d, j=%d, sum=%f\n", id, startIndex, endIndex, sum); } public static double[] generateData(int n, double min, double max) { double[] data = new double[n]; double range = max - min + 1; //for (double d : data) { // Exercise: why wouldn't this work? // d = Math.random() * range + min; // } // Math.random() ==> [0, 1) ==> [min, max] for (int i = 0; i < n; ++i) { data[i] = (int) (Math.random() * range + min); // store range + min?? NO, why? } return data; } public static void main(String[] args) { // get data int dataSize = 10; int nWorkers = 1; double[] data = generateData(dataSize, 1, 9); // timing the performance long startTime = System.nanoTime(); // assumption: dataSize is divisible by nWorkers // divide work equally among threads int workSize = dataSize / nWorkers; SumThread[] workers = new SumThread[nWorkers]; // // startIndex = i * workSize; // endIndex = (i + 1) * workSize - 1; // startIndex + workSize - 1 // start/end-index for thread 0 int startIndex = 0; int endIndex = workSize - 1; for (int i = 0; i < nWorkers; ++i) { workers[i] = new SumThread(data, i, startIndex, endIndex); startIndex += workSize; endIndex += workSize; } // start threads for (Thread st : workers) { st.start(); } // wait until ALL threads are done try { for (SumThread st : workers) { st.join(); } } catch(InterruptedException e) { System.err.println("Workers were unable to complete their work due to interruptions"); e.printStackTrace(); } // collect the result double sum = 0.0; for (SumThread st : workers) { // cannot use Thread type sum += st.getResult(); } long endTime = System.nanoTime(); // publish the result System.out.printf("dataSize: %d, nWorkers: %d, result: %.2f, time (ns): %d\n", dataSize, nWorkers, sum, (endTime - startTime)); System.out.printf("verification data: %s\n", Arrays.toString(data)); } }