Parallel Sum with Threads
Problem
Read an array and a number k of worker threads. Split the array into k parts, let each worker sum one part, and add the partial sums to get the total. Print the total. (If k is larger than n, some workers get an empty part.)
Constraints
- 1 <= n <= 10^5
- 1 <= k <= 64
Examples
Input
10 1 2 3 4 5 6 7 8 9 10 3
Output
55
Solutions
Splitting work into independent parts is the safest way to use threads, because the threads share no writable data. The main thread waits with join and then combines the results. For JavaScript the example only shows the split-and-combine idea, because JavaScript code runs on one thread (real parallel work would use Worker threads).
/*
* Problem : Process an array.
* Input : n, then n integers.
* Output : The total.
* Approach: Split, sum in threads, join.
* Time : O(n / k)
* Space : O(k)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static long solve(int[] a, int k) {
// Step 1: Each worker writes its result in its own place in this array. No two threads write to the same place.
long[] partial = new long[k];
Thread[] workers = new Thread[k];
int chunk = (a.length + k - 1) / k;
for (int w = 0; w < k; w++) {
final int id = w;
// Step 2: Each worker sums its own part: the indexes from id * chunk to (id + 1) * chunk.
workers[w] = new Thread(() -> {
long sum = 0;
for (int i = id * chunk; i < Math.min(a.length, (id + 1) * chunk); i++) {
sum += a[i];
}
partial[id] = sum;
});
workers[w].start();
}
// Step 3: join waits until a worker is finished. After all joins, every partial sum is ready.
long total = 0;
for (int w = 0; w < k; w++) {
try {
workers[w].join();
} catch (InterruptedException error) {
Thread.currentThread().interrupt();
}
total += partial[w];
}
return total;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] a = new int[size];
for (int i = 0; i < size; i++) {
a[i] = scanner.nextInt();
}
int k = scanner.nextInt();
System.out.println(solve(a, k));
}
}
Hints (2)
- Why can each worker write to its own array place without a lock?
- What does join do?