在大型整數陣列中尋找最大值。採用分而治之:將陣列分塊,各塊並行求最大值,再合併結果。
public class MaxNumberFinder {
static final int THRESHOLD = 50;
static int[] createArray(int n) { /* 隨機生成 */ }
static int getMax(int[] a) { /* 線性掃描 */ }
static int findMax(int[] a) {
int[] maxs = new int[(a.length + THRESHOLD - 1) / THRESHOLD];
for (int i = 0; i < a.length; i += THRESHOLD) {
int end = Math.min(i + THRESHOLD, a.length);
maxs[i / THRESHOLD] = getMax(Arrays.copyOfRange(a, i, end));
}
return maxs.length > THRESHOLD ? findMax(maxs) : getMax(maxs);
}
}
static int findMaxThread(int[] a) {
int[] maxs = new int[...];
List threads = new ArrayList<>();
for (int i = 0; i < a.length; i += THRESHOLD) {
final int idx = i / THRESHOLD;
final int[] sub = Arrays.copyOfRange(a, i, Math.min(i + THRESHOLD, a.length));
Thread t = new Thread(() -> maxs[idx] = getMax(sub));
t.start(); threads.add(t);
}
for (Thread t : threads) try { t.join(); } catch (InterruptedException ignored) {}
return maxs.length > THRESHOLD ? findMaxThread(maxs) : getMax(maxs);
}
缺點:大量線程創建/銷毀開銷、高層線程阻塞等待低層、難以控制併發度。
static final ExecutorService pool = Executors.newCachedThreadPool();
static int findMaxFuture(int[] a) {
int[] maxs = new int[...];
List> futures = new ArrayList<>();
for (int i = 0; i < a.length; i += THRESHOLD) {
final int[] sub = Arrays.copyOfRange(a, i, Math.min(i + THRESHOLD, a.length));
futures.add(pool.submit(() -> getMax(sub)));
}
for (int i = 0; i < futures.size(); i++)
try { maxs[i] = futures.get(i).get(); } catch (Exception ignored) {}
return maxs.length > THRESHOLD ? findMaxFuture(maxs) : getMax(maxs);
}
Future.get() 隱含阻塞等待,效果等同 join(),但線程池複用線程,減少創建開銷。
class MaxTask extends RecursiveTask{ private final int[] data; MaxTask(int[] d) { this.data = d; } @Override protected Integer compute() { if (data.length <= THRESHOLD) return getMax(data); int mid = data.length / 2; MaxTask left = new MaxTask(Arrays.copyOfRange(data, 0, mid)); MaxTask right = new MaxTask(Arrays.copyOfRange(data, mid, data.length)); invokeAll(left, right); return Math.max(left.join(), right.join()); } } // 使用 ForkJoinPool pool = new ForkJoinPool(); int max = pool.invoke(new MaxTask(array));
優點:工作竊取演算法自動負載均衡、遞歸任務分解自然映射、API 簡潔、針對多核優化。