import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class InvokeAllInvokeAny {
    public static void main(String[] args) throws Exception {
        // Bentuk modern sejak Java 19: try-with-resources -- close() akan
        // mematikan eksekutor dan menunggu task berjalan sampai selesai.
        try (ExecutorService eksekutor = Executors.newFixedThreadPool(3)) {

            // invokeAll: kirim ketiga task, tunggu SEMUANYA selesai.
            // Hasil Future terurut sesuai urutan pengiriman, bukan urutan selesai.
            List<Callable<Integer>> daftarTugas = List.of(
                    () -> { Thread.sleep(80); return 10; }, // paling lambat
                    () -> 20,                                 // tercepat
                    () -> { Thread.sleep(40); return 30; }   // sedang
            );
            List<Future<Integer>> hasilAll = eksekutor.invokeAll(daftarTugas);
            System.out.println("invokeAll -- hasil sesuai urutan pengiriman:");
            for (int i = 0; i < hasilAll.size(); i++) {
                System.out.println("  task ke-" + (i + 1) + ": " + hasilAll.get(i).get());
            }

            // invokeAny: kembali dengan hasil task yang PERTAMA berhasil.
            // Ketiga task sengaja mengembalikan teks yang sama agar keluaran
            // tidak bergantung pada task mana yang memenangkan perlombaan.
            List<Callable<String>> pemeriksaan = new ArrayList<>();
            for (int sumber = 1; sumber <= 3; sumber++) {
                int jeda = sumber * 40; // tiap sumber punya kecepatan berbeda
                pemeriksaan.add(() -> {
                    Thread.sleep(jeda);
                    return "stok tersedia";
                });
            }
            String hasilAny = eksekutor.invokeAny(pemeriksaan);
            System.out.println("invokeAny -- hasil: " + hasilAny);
        }
    }
}
