1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class LeakyBucketRateLimit implements RateLimit,Runnable{
private Integer limitSecond;
private BlockingDeque<Thread> leakyBucket; private ScheduledExecutorService scheduledExecutorService;
public LeakyBucketRateLimit(Integer bucketSize, Integer limitSecond) { this.limitSecond = limitSecond; this.leakyBucket = new LinkedBlockingDeque<>(bucketSize); scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); long interval = (1000 * 1000 * 1000) / limitSecond; scheduledExecutorService.scheduleAtFixedRate(this, 0, interval, TimeUnit.NANOSECONDS); }
@Override public boolean canPass() throws RuntimeException { if(leakyBucket.remainingCapacity() == 0){ throw new RuntimeException(); } leakyBucket.offer(Thread.currentThread()); LockSupport.park(); return true; }
@Override public void run() { Thread thread = leakyBucket.poll(); if(Objects.nonNull(thread)){ LockSupport.unpark(thread); } }
public static void main(String[] args) throws RuntimeException { LeakyBucketRateLimit leakyBucketRateLimit = new LeakyBucketRateLimit(100, 1); for (int i = 0; i < 10000; i++){ if(leakyBucketRateLimit.canPass()){ System.out.println("通过第【" + i + "】个请求"); } } } }
|