public class RateLimit {
private long bucketSize;
private double currentNum;
private double rate;
// 最后一次加水时间
private long lastTime;
private Lock lock;
public static RateLimit create(long ticketPerSecond) {
RateLimit rateLimit = new RateLimit();
rateLimit.bucketSize = ticketPerSecond;
rateLimit.currentNum = 0;
rateLimit.rate = ticketPerSecond;
rateLimit.lastTime = System.currentTimeMillis();
rateLimit.lock = new ReentrantLock();
return rateLimit;
}
public boolean tryAcquire() {
try {
lock.lock();
long curTime = System.currentTimeMillis();
this.currentNum = Math.max(0, currentNum - (curTime - lastTime) * rate / 1000);
lastTime = curTime;
if (bucketSize - currentNum >= 1) {
currentNum++;
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return false;
}
public static void main(String[] args) {
final RateLimit rateLimit = create(5);
while (true) {
System.out.println(rateLimit.tryAcquire() + " - " + Thread.currentThread().getId() + " - " + System.currentTimeMillis() + " - " + rateLimit.currentNum);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}