Java ExecutorService,为队列中的所有工作设置总体固定速率

时间:2015-01-29 22:06:27

标签: java asynchronous concurrency java.util.concurrent

鉴于以下代码:

ScheduledExecutorService es = new ScheduledThreadPoolExecutor(100);

es.scheduleAtFixedRate(() -> {
        System.out.println("Do work with a fixed rate! ");
}, 0, 1000, TimeUnit.MILLISECONDS);


int i = 0;
while ( i < 100 ) {
        es.scheduleAtFixedRate(() -> {
                System.out.println("Do more work with a fixed rate! Doesn't really work! We will end up with 100 'workers', each running with a fixed rate! ");
        }, 0, 1000, TimeUnit.MILLISECONDS);

        i++;
}

创建 SchedueledThreadPoolExecutor

在while循环中,我们正在模拟其他想要在队列中添加更多工作的人,但这显然不起作用。

我猜,需要实现某种ThreadPoolExecutor,它使用某种队列,可能是延迟队列。

这个想法是创建执行程序,然后它具有可以执行任务的固定速率。如果任务完成得太快,那么已完成的线程需要等待才能完成更多的工作。

如果一个完成得太慢,那么全局时间应该允许线程池中的其他线程完成更多的工作。

http://docs.oracle.com/javase/7/docs/api/java/util/AbstractQueue.html

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/DelayQueue.html

但是我希望这已经完成了,因为它应该是非常常见的问题。

有没有人有这个好的解决方案?

2 个答案:

答案 0 :(得分:0)

目前还不完全清楚你想做什么,但我的猜测是你需要一种Pacer或Throttler来确保以一定的速率执行任务(想想办公楼入口处的旋转门和其他,门的速度决定了每个时间单位可以进入(或退出)建筑物的人数以及每个入口(或出口)之间的时差。)

ScheduledExecutorServcice 不是解决该问题的方法。相反,首先研究Leaky Bucket Algorithm

答案 1 :(得分:0)

ScheduledThreadPoolExecutor维护由任务下次计划执行排序的任务队列。这些任务(您提供的Runnable实例)完全独立于将执行它们的线程。换句话说,线程不只是获取任务,执行它,然后进入休眠状态等待该任务的下一次执行。

相反,线程轮询队列,获取任务,执行它,通过将其重新插入队列来安排下一次执行任务,然后再次轮询队列。如果队列有任务,那很好。如果没有,他们会等到下一个任务准备就绪(无论是当前在队列中还是在以后添加)。然后他们重新启动整个过程。

所有这一切都表明,拥有100个线程的ScheduledThreadPoolExecutor可以轻松处理任何类型的100多个任务。