package com.ycwl.basic.ratelimiter; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; public class SlidingWindowRateLimiter { private final Semaphore semaphore; private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); public SlidingWindowRateLimiter(int maxRequestsPerSecond) { this.semaphore = new Semaphore(maxRequestsPerSecond); // Schedule a task to release all permits every second scheduler.scheduleAtFixedRate(() -> semaphore.release(maxRequestsPerSecond - semaphore.availablePermits()), 1, 1, TimeUnit.SECONDS); } public void allowRequest() throws InterruptedException { semaphore.acquire(); } public void shutdown() { scheduler.shutdown(); } }