import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class JadwalSekali {

    record Tugas(String nama, long jedaMilidetik) {}

    public static void main(String[] args) throws Exception {
        ScheduledExecutorService penjadwal = Executors.newScheduledThreadPool(2);

        // Tiga task sekali jalan: jeda menentukan kapan masing-masing berjalan.
        List<Tugas> jadwal = List.of(
                new Tugas("cetak-laporan", 0),
                new Tugas("kirim-pengingat", 300),
                new Tugas("arsipkan-transaksi", 150));

        Queue<String> urutanSelesai = new ConcurrentLinkedQueue<>();
        List<ScheduledFuture<String>> hasil = new ArrayList<>();
        for (Tugas t : jadwal) {
            hasil.add(penjadwal.schedule(
                    () -> {
                        urutanSelesai.add(t.nama());
                        return t.nama() + " selesai";
                    },
                    t.jedaMilidetik(), TimeUnit.MILLISECONDS));
        }

        // get() menunggu tiap task tuntas; nilai baliknya utuh.
        for (ScheduledFuture<String> f : hasil) {
            f.get();
        }

        System.out.println("urutan didaftarkan: "
                + jadwal.stream().map(Tugas::nama).toList());
        System.out.println("urutan selesai    : " + urutanSelesai.stream().toList());
        System.out.println("nilai get() ke-2  : " + hasil.get(1).get());

        // Thread pekerja bukan daemon: tanpa shutdown, JVM tidak akan keluar.
        penjadwal.shutdown();
    }
}
