import java.time.Instant;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Testy {
    public static void main(String[] args) throws InterruptedException {
        ScheduledThreadPoolExecutor scheduledExecutorService = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(Integer.MAX_VALUE);

// comment out below line to restore expected behavior
        //scheduledExecutorService.allowCoreThreadTimeOut(true);

        Callable<String> scheduledCallable1 = () -> {
            Thread.sleep(5000);
            System.out.println(Instant.now() + " T1 done");
            return "Done";
        };
        Callable<String> scheduledCallable2 = () -> {
            Thread.sleep(5000);
            System.out.println(Instant.now() + " T2 done");
            return "Done";
        };
        Runnable scheduledRunnable = () -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {}
            System.out.println(Instant.now() + " R done");
        };

// comment in below two lines to "fix" behavior
        Future<String> future1 = scheduledExecutorService.submit(() -> {
// will not work without this sleep to cause it to overlap with the schedule time of scheduledCallable1/2
            Thread.sleep(2000);
            System.out.println(Instant.now() + " directly submitted 1");
            return "Done";});
        Future<String> future2 = scheduledExecutorService.submit(() -> {
            Thread.sleep(2000);
            System.out.println(Instant.now() + " directly submitted 2");
            return "Done";});

        scheduledExecutorService.schedule(scheduledCallable1, 1, TimeUnit.SECONDS);
        scheduledExecutorService.schedule(scheduledCallable2, 1, TimeUnit.SECONDS);
        scheduledExecutorService.scheduleAtFixedRate(scheduledRunnable, 1, 1, TimeUnit.SECONDS);

        while(true) {
            Thread.sleep(10000);
            System.out.println(Instant.now() + " slept 10000");
        }
    }
} 