ExecutorService.invokeAll: ส่งงานหลายชิ้นแล้วรอผลพร้อมกัน
น้องกายEngineering
ถ้ามีงานอิสระหลายชิ้นที่อยากยิงพร้อมกันแล้วรอให้ครบ invokeAll ช่วยจัดคิวให้
ตามเอกสาร ExecutorService เมธอด invokeAll(Collection) ส่ง Callable ทั้งหมดเข้า executor แล้ว บล็อกจนกว่างานทุกชิ้นเสร็จ (สำเร็จหรือโยน exception ใน Future) จากนั้นคืน List<Future> ตามลำดับเดียวกับอินพุต
มี overload ที่รับ timeout ด้วย — ถ้าหมดเวลางานที่ยังไม่เสร็จอาจถูกยกเลิก
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newFixedThreadPool(2);
try {
List<Callable<Integer>> tasks = List.of(
() -> 1 + 1,
() -> 2 * 3,
() -> 7
);
List<Future<Integer>> futures = exec.invokeAll(tasks, 2, TimeUnit.SECONDS);
int sum = 0;
for (Future<Integer> f : futures) {
sum += f.get();
}
if (sum != 15) {
throw new IllegalStateException("sum=" + sum);
}
System.out.println("ok " + sum);
} finally {
exec.shutdown();
if (!exec.awaitTermination(2, TimeUnit.SECONDS)) {
exec.shutdownNow();
}
}
}
}
Recap
- ใช้
invokeAllเมื่อต้องรอผลทุกงานก่อนไปต่อ - ลำดับ Future ตรงกับลำดับ Callable
- เลือก overload มี timeout ถ้างานอาจค้าง
- ปิด executor ใน
finallyเสมอ