有节奏任务控制器的目的是接受一个任务,并在客户端代码定义的循环或“节律”中执行所有排队的任务。任务返回true或false,取决于它是否“完成”。完成的任务应该从控制器的控件中移除,并且不会再次执行,而未完成的任务应该在下一个周期中执行。
我不认为我的解决方案是尽可能优化的,这是一个解决方案,需要尽可能快,因为它作为核心任务控制器在我的游戏框架!
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();
}
});
}
}
发布于 2015-04-06 04:46:22
这是一个解决方案,需要尽可能快,因为它作为核心任务控制器在我的游戏框架!
不一定。这都取决于一项任务平均承担了多少。除非你的任务非常快,否则,在他们的队列中鬼鬼祟祟并不重要。
@Override
public void offer(Task task) {
queue.offer(task);
}
在不检查返回值的情况下,不要使用offer
。只要您使用ConcurrentLinkedQueue
,就可以了,但是当您切换实现时,它就会在没有任何警告的情况下停止工作。使用类似的东西
com.google.common.base.Verify(queue.offer(task));
除非删除是常见的,否则我猜您的原始实现比SpiderPig的解决方案在每次迭代中删除和重新添加任务要快。通常,迭代集合比修改集合快(两次)。但这只是猜测..。度量可以告诉您,但是度量Java性能很难。
发布于 2015-04-05 23:49:22
您可以从队列中删除所有元素,并在必要时提供它们。
public void run() {
ArrayList<Task> tasks = new ArrayList<>();
{
Task task;
while((task = queue.poll()) != null) {
tasks.add(task);
}
}
for(Task task: tasks) {
service.submit(() -> {
if(!task.finish()) offer(task);
});
}
}
https://codereview.stackexchange.com/questions/85961
复制相似问题