Bu uygulamaya bağlıdır.
Hangi durumda hayal Birden çok iş parçacığı bazı yapmak için bir belirteç istediğiniz global hız sınırlı eylemi ile izin kaymalarının hayır yani 10 saniye başına 10 eylemleri sınırlamak istiyorsanız (ama 10 eylemleri ilk saniyede gerçekleşmesini istiyor ve ardından kalmaz 9 saniye durdu).
DelayedQueue'nin bir dezavantajı vardır: iş parçacığı istek belirteçlerinin hangi sırada isteklerini yerine getirdikleri sırası olmayabilir. Bir simgeyi beklerken birden fazla iş parçacığı engellenirse, hangisinin bir sonraki kullanılabilir simgeyi alacağı net değildir. Benim görüşüme göre sonsuza kadar bekleyen iplikler bile olabilir.
Bir çözüm, birbirini takip eden iki eylem arasında minimum zaman aralığına sahip olmak ve eylemleri talep edilen sırayla gerçekleştirmektir.
İşte bir uygulama:
public class LeakyBucket {
protected float maxRate;
protected long minTime;
//holds time of last action (past or future!)
protected long lastSchedAction = System.currentTimeMillis();
public LeakyBucket(float maxRate) throws Exception {
if(maxRate <= 0.0f) {
throw new Exception("Invalid rate");
}
this.maxRate = maxRate;
this.minTime = (long)(1000.0f / maxRate);
}
public void consume() throws InterruptedException {
long curTime = System.currentTimeMillis();
long timeLeft;
//calculate when can we do the action
synchronized(this) {
timeLeft = lastSchedAction + minTime - curTime;
if(timeLeft > 0) {
lastSchedAction += minTime;
}
else {
lastSchedAction = curTime;
}
}
//If needed, wait for our time
if(timeLeft <= 0) {
return;
}
else {
Thread.sleep(timeLeft);
}
}
}