简体   繁体   English

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

[英]Java ExecutorService, setting an overall fixed rate for all work in a queue

Given the below code: 给出以下代码:

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++;
}

which creates a SchedueledThreadPoolExecutor . 这将创建一个SchedueledThreadPoolExecutor

In the while loop, we are simulating someone else wanting to add more work to the queue, but this won't obviously work. 在while循环中,我们正在模拟其他想要向队列添加更多工作的人,但这显然行不通。

I am guessing, that one needs to implement some sort of ThreadPoolExecutor which uses a Queue of some sort, possibly a delayed queue. 我猜想,一个人需要实现某种ThreadPoolExecutor,它使用某种队列,可能是延迟队列。

The idea is that the executor is created and then it has a fixed rate at which it can execute tasks. 这个想法是创建执行程序,然后以固定的速率执行任务。 If a task finishes too quickly threads that have finished need to wait to do pull off more work. 如果任务完成得太快,则需要等待完成的线程才能完成更多工作。

If one finishes too slowly, then the global time should allow other threads in the threadpool to pull off more work. 如果一个进程完成得太慢,则全局时间应允许线程池中的其他线程完成更多工作。

http://docs.oracle.com/javase/7/docs/api/java/util/AbstractQueue.html 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 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/DelayQueue.html

But I was hoping this was already done, as it should be pretty common problem. 但是我希望这已经完成,因为这应该是很常见的问题。

Does anyone have a good solution to this? 有人对此有很好的解决方案吗?

It is not entirely clear what you want to do, but my guess is that you want a kind of Pacer or Throttler that ensures that tasks are executed with a certain rate (think of the revolving doors found at entrances to office buildings and others, the speed of the door determines the number of persons that can enter (or exit) the building per time unit and the time difference between each entrance (or exit)). 目前尚不清楚您要做什么,但是我想您想要一种起搏器或节流阀,以确保以一定的速率执行任务(想想在办公楼和其他建筑物入口处发现的旋转门,门的速度决定了每个时间单位可进入(或离开)建筑物的人数以及每个入口(或出口)之间的时间差。

ScheduledExecutorServcice is not a solution for that problem. ScheduledExecutorServcice 不能解决该问题。 Instead, start by studying the Leaky Bucket Algorithm . 相反,首先要研究“ 漏桶”算法

A ScheduledThreadPoolExecutor maintains a queue of tasks that is ordered by the tasks' next scheduled execution. ScheduledThreadPoolExecutor维护任务队列,这些任务由任务的下一个计划执行顺序排序。 These tasks (the Runnable instances you provide) are completely independent of the threads that will execute them. 这些任务(您提供的Runnable实例)完全独立于将执行它们的线程。 In other words, the threads don't just acquire a task, execute it, then go to sleep waiting for that task's next execution. 换句话说,线程不仅获取任务,执行任务,然后进入睡眠状态等待任务的下一次执行。

Instead, the threads poll the queue, acquire a task, execute it, schedule the next execution of their task by reinserting it into the queue, then poll the queue again. 而是,线程轮询队列,获取任务,执行任务,通过将任务重新插入队列来安排任务的下一次执行,然后再次轮询队列。 If the queue has a task, great. 如果队列中有任务,那就太好了。 If not, they wait until the next task is ready (whether it's currently in the queue or added at a later time). 如果没有,他们将等到下一个任务准备就绪(无论它当前在队列中还是以后添加)。 They then restart this whole process. 然后,他们重新启动整个过程。

All this to say, that a ScheduledThreadPoolExecutor with 100 threads can easily process more than 100 tasks at any type of rate. 综上所述,具有100个线程的ScheduledThreadPoolExecutor可以轻松地以任何类型的速率处理100多个任务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM