The purpose of a rhythmic task controller is to accept a task and execute all the queued tasks in a cycle or "rhythm" defined by the client code. A task returns true or false depending on whether or not it is "finished". A finished task should be removed from the controller's control and won't be executed again while an unfinished task should be executed on the next cycle.
I don't think my solution is as well optimized as it could be, and this is a solution that needs to be as fast as possible as it serves as the core task controller in my game framework!
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public final class RhythmicTaskController implements TaskController, Runnable {
private final ExecutorService service;
private final ConcurrentLinkedQueue<Task> queue = new ConcurrentLinkedQueue<>();
public RhythmicTaskController(int threads, int delay, TimeUnit unit) {
service = Executors.newFixedThreadPool(threads);
newSingleThreadScheduledExecutor().scheduleWithFixedDelay(this, delay, delay, unit);
}
@Override
public void offer(Task task) {
queue.offer(task);
}
@Override
public void run() {
int initial = queue.size();
ConcurrentMap<Future<Boolean>, Task> futures = new ConcurrentHashMap<>(initial);
queue.forEach(task -> futures.put(service.submit(task::finish), task));
futures.forEach((r, task) -> {
try {
if (r.get())
queue.remove(task);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
while (futures.size() < initial);
is really bad style. You should never use an empty while loop to wait for something. It will load one of your CPU cores to 100% for that time. Plus I don't see how futures.size() could ever be less than initial since you never remove anything from the map. \$\endgroup\$