import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;

public class VirtualThreadDeadlock {

    public static void main(String[] args) throws Exception {
// use jdk.virtualThreadScheduler.parallelism=1 to reproduce the issue easily
        System.setProperty("jdk.virtualThreadScheduler.parallelism", "1");

        ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();

        CountDownLatch latch = new CountDownLatch(2);

        ReentrantLock lock = new ReentrantLock();

        Object objLock = new Object();

        lock.lock(); // main thread locked
        System.out.println("Main thread lock");

        executor.execute(() -> {
            lock.lock(); // try to lock, continuation will yield
            try {
                System.out.println("First thread lock");
            } finally {
                lock.unlock();
                System.out.println("First thread unlock");
            }

            latch.countDown(); // first thread end
        });

        Thread.sleep(1000);

        executor.execute(() -> {
            synchronized (objLock) {
                lock.lock(); // carrierThread will be pinned
                try {
                    System.out.println("Second thread lock");
                } finally {
                    lock.unlock();
                    System.out.println("Second thread unlock");
                }
            }

            latch.countDown(); // second thread end
        });

        Thread.sleep(1000);

        lock.unlock(); // main thread unlocked, the first thread is supposed to continue,
// but there is no available carrierThread to execute

        System.out.println("Main thread unlock");

        latch.await();

        System.out.println("Suppose to be here!!");
    }

} 