10 個線程分別計算:1-10、11-20、...、91-100 的和,主線程匯總輸出總和 (5050)。
join(),導致實際單線程執行times++ 無同步,多線程競爭導致結果錯誤import java.util.concurrent.*;
public class SumCalculator {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(10);
List> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
final int start = i * 10 + 1;
final int end = (i + 1) * 10;
futures.add(executor.submit(() -> {
int sum = 0;
for (int j = start; j <= end; j++) sum += j;
return sum;
}));
}
int total = 0;
for (Future f : futures) {
total += f.get(); // 阻塞獲取結果
}
System.out.println("總和: " + total); // 5050
executor.shutdown();
}
}
// 一行代碼實現並行求和
int total = IntStream.rangeClosed(1, 100)
.parallel()
.sum();
System.out.println(total); // 5050
| 維度 | 原代碼 | 優化方案一 | 並行流 |
|---|---|---|---|
| 並行度 | 串行 (join) | 真並行 (線程池) | 自動並行 |
| 線程安全 | 無同步 | 無共享狀態 | 框架保證 |
| 代碼量 | ~50 行 | ~25 行 | 1 行 |
| 可維護性 | 低 | 高 | 極高 |
// ❌ 危險:times++ 非原子操作 (讀-改-寫)
static int times = 0;
// 線程 A: 讀取 times=5
// 線程 B: 讀取 times=5
// 線程 A: 寫入 6
// 線程 B: 寫入 6 (丟失一次更新)
// ✅ 方案:AtomicInteger
AtomicInteger times = new AtomicInteger(0);
times.incrementAndGet(); // 原子操作
// ✅ 方案:synchronized
synchronized(lock) { times++; }
// ✅ 方案:ThreadLocal + 最終匯總 (無競爭)
ExecutorService 管理線程生命周期Future.get() 收集結果,主線程匯總parallelStream / IntStream.parallelexecutor.shutdown()