import java.time.Duration;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main {
    public static void main(String[] args) {
        try (final var pool = Executors.newVirtualThreadPerTaskExecutor()) {
            final var futures = new ArrayList<Future<Integer>>();
            for (int i = 0; i < 10; i += 1) {
                final var id = i;
                final var future = pool.submit(() -> {
                    try {
                        Thread.sleep(Duration.ofSeconds(4));
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.printf("Thread: (%d) %s%n", id, Thread.currentThread().getName());
                    return 0;
                });
                futures.add(future);
            }
            futures.forEach(future -> {
                try {
                    future.get();
                } catch (InterruptedException | ExecutionException e) {
                    throw new RuntimeException(e);
                }
            });
        }
    }
}