यह एप्लिकेशन में निर्भर करता है।
उस मामले की कल्पना करें जिसमें कई धागे चाहते हैं कि कोई भी वैश्विक स्तर पर सीमित-सीमित कार्रवाई के साथ कोई फट की अनुमति न हो (यानी आप प्रति सेकंड 10 क्रियाओं को सीमित करना चाहते हैं, लेकिन आप नहीं चाहते कि 10 क्रियाएं पहले दूसरे में हों और फिर रहें 9 सेकंड रुक गए)।
DelayedQueue का एक नुकसान है: जिस क्रम पर धागे अनुरोध करते हैं, टोकन वह आदेश नहीं हो सकता है जिस पर वे अपना अनुरोध पूरा करते हैं। यदि कई थ्रेड्स टोकन के इंतजार में अवरुद्ध हैं, तो यह स्पष्ट नहीं है कि कौन सा अगले उपलब्ध टोकन लेगा। तुम भी हमेशा के लिए मेरी बात में इंतज़ार कर धागे हो सकता है।
एक समाधान के लिए दो लगातार क्रियाओं के बीच समय का न्यूनतम अंतराल होना चाहिए , और उसी क्रम में कार्रवाई करना चाहिए जैसा कि उनसे अनुरोध किया गया था।
यहाँ एक कार्यान्वयन है:
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);
}
}
}