Careeroza
Real World Example
Notification Fan-out (Gmail / Swiggy style)
When a sale starts, an app may send push notifications to thousands of users. Each send is a slow HTTP call to a push service. With virtual threads each send is simple blocking code, and a Semaphore respects the provider's limit of concurrent calls.
Example
5,000 notifications, at most 500 in flight, each call takes 200 ms.
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class Main {
static final Semaphore PROVIDER_LIMIT = new Semaphore(500);
static final AtomicInteger sent = new AtomicInteger();
static final AtomicInteger failed = new AtomicInteger();
static void sendPush(int userId) throws InterruptedException {
PROVIDER_LIMIT.acquire();
try {
Thread.sleep(200); // HTTP call to the push provider
if (userId % 1000 == 999) throw new IllegalStateException("invalid device token");
sent.incrementAndGet();
} catch (IllegalStateException e) {
failed.incrementAndGet();
} finally {
PROVIDER_LIMIT.release();
}
}
public static void main(String[] args) {
long start = System.nanoTime();
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int user = 0; user < 5_000; user++) {
final int id = user;
executor.submit(() -> { sendPush(id); return null; });
}
}
long ms = (System.nanoTime() - start) / 1_000_000;
System.out.println("Sent: " + sent.get() + ", failed: " + failed.get());
System.out.println("About 2 seconds (10 waves of 500 x 200 ms), not 1000 s: " + (ms < 6000));
}
}Output
Sent: 4995, failed: 5 About 2 seconds (10 waves of 500 x 200 ms), not 1000 s: true