Semaphore limits how many run at once

A semaphore hands out a fixed number of permits, which is how you cap concurrent access to a scarce resource such as a connection pool.

Code
var semaphore = new Semaphore(2);
var maxSeen = new AtomicInteger();
var inFlight = new AtomicInteger();

try (var pool = Executors.newVirtualThreadPerTaskExecutor()) {
    for (int i = 0; i < 10; i++) {
        pool.submit(() -> {
            semaphore.acquire();
            try {
                maxSeen.accumulateAndGet(inFlight.incrementAndGet(), Math::max);
                Thread.sleep(Duration.ofMillis(10));
            } finally {
                inFlight.decrementAndGet();
                semaphore.release();
            }
            return null;
        });
    }
}

System.out.println("permits = 2, peak concurrent = " + maxSeen.get());
Output
permits = 2, peak concurrent = 2
Advertisement

Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.

Published 2026-07-30