鉴于以下代码:
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
但是我希望这已经完成了,因为它应该是非常常见的问题。
有没有人有这个好的解决方案?
答案 0 :(得分:0)
目前还不完全清楚你想做什么,但我的猜测是你需要一种Pacer或Throttler来确保以一定的速率执行任务(想想办公楼入口处的旋转门和其他,门的速度决定了每个时间单位可以进入(或退出)建筑物的人数以及每个入口(或出口)之间的时差。)
ScheduledExecutorServcice 不是解决该问题的方法。相反,首先研究Leaky Bucket Algorithm。
答案 1 :(得分:0)
ScheduledThreadPoolExecutor
维护由任务下次计划执行排序的任务队列。这些任务(您提供的Runnable
实例)完全独立于将执行它们的线程。换句话说,线程不只是获取任务,执行它,然后进入休眠状态等待该任务的下一次执行。
相反,线程轮询队列,获取任务,执行它,通过将其重新插入队列来安排下一次执行任务,然后再次轮询队列。如果队列有任务,那很好。如果没有,他们会等到下一个任务准备就绪(无论是当前在队列中还是在以后添加)。然后他们重新启动整个过程。
所有这一切都表明,拥有100个线程的ScheduledThreadPoolExecutor
可以轻松处理任何类型的100多个任务。