我试图理解java.util.concurrent.Executor接口的下面的示例实现,它是在API中提供的。
class SerialExecutor implements Executor {
final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
final Executor executor;
Runnable active;
SerialExecutor(Executor executor) {
this.executor = executor;
}
public synchronized void execute(final Runnable r) {
tasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (active == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((active = tasks.poll()) != null) {
executor.execute(active);
}
}
}在这里,传递的Runnable实例被包装到另一个Runnable实例中,并存储在任务队列中,然后调用scheduleNext()。传递的可运行实例是否复制(防御)到其他可运行实例?如果没有,除了从队列中执行下一个Runnable之外,这样做有什么用?
请澄清我的疑虑。
发布于 2014-11-26 02:04:58
您只希望在第一个任务完成后才对第二个任务进行scheduleNext()。
将原始的Runnable封装到另一个调用它的程序中,然后调用scheduleNext()是一种方便和可靠的方法。
这样,您就可以只使用一个线程进行“生产性使用”和“队列管理”。
替代方案是一个单独的后台线程,它监视当前正在运行的任务(例如,通过join() ),然后安排一个新的任务。
传递的可运行实例是否复制(防御)到其他可运行实例?
不怎么有意思。当然,指向Runnable的指针是复制的,但是它仍然指向相同的Runnable。这不是“防御性的”,因为理论上跑步者的状态可以在排队时被更新。
如果没有,除了从队列中执行下一个Runnable之外,这样做有什么用?
为什么这个理由还不够?毕竟,这是必须做的。
https://stackoverflow.com/questions/27140050
复制相似问题