Simple Java Throttler

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* Executes M tasks every N timeunits
* @author eolivelli@gmail.com
*/
public class Throttler {
private static class Task implements Delayed {
long trigger;
Task(long i) {
trigger = System.nanoTime() + i;
}
public int compareTo(Delayed y) {
long i = trigger;
long j = ((Task) y).trigger;
if (i < j) {
return -1;
}
if (i > j) {
return 1;
}
return 0;
}
public boolean equals(Object other) {
return ((Task) other).trigger == trigger;
}
public long getDelay(TimeUnit unit) {
long n = trigger - System.nanoTime();
return unit.convert(n, TimeUnit.NANOSECONDS);
}
}
private DelayQueue window = new DelayQueue();
private int numTasks;
private int timeUnits;
private TimeUnit timeUnit;
private ExecutorService executor;
private LinkedBlockingQueue tasks = new LinkedBlockingQueue();
private Thread thread;
private boolean requestedstop;
public Throttler(int numTasks, int timeUnits, TimeUnit timeUnit, ExecutorService executor) {
this.numTasks = numTasks;
this.timeUnits = timeUnits;
this.timeUnit = timeUnit;
this.executor = executor;
for (int i = 0; i < numTasks; i++) {
window.add(new Task(0));
}
thread = new Thread(new Runner());
thread.setDaemon(false);
thread.start();
}
public void submit(Runnable task) {
tasks.add(task);
}
public void stop() {
requestedstop = true;
}


private class Runner implements Runnable {
@Override
public void run() {
while (!requestedstop) {
try {
// System.out.println("Waiting for a task..." + System.currentTimeMillis() + " " + window);
window.take();
// System.out.println("poll a task.."+tasks);
Runnable r = tasks.poll();
if (r != null) {
//System.out.println("executing task " + r);
executor.submit(r);
}
long delay = TimeUnit.NANOSECONDS.convert(timeUnits, timeUnit);
// System.out.println("delay=" + delay);
window.add(new Task(delay));
} catch (InterruptedException ex) {
return;
}
}
}
}
}
 
Powered by MagNews
RSS feed for this site