Java 异构任务集的动态优先级
我有一大堆重复的任务要安排。他们查询数据库,找出该做什么,然后执行一些操作,如更新统计数据、发送电子邮件、获取文件和导入它们。目前,大概有十家,这个数字预计会增长很多。我没有任何时间限制,事实上,我的工作就是选择一种算法,这样就不会有人抱怨了D 目前,我正在使用线程和定期计划任务的临时组合,如Java 异构任务集的动态优先级,java,scheduler,job-scheduling,Java,Scheduler,Job Scheduling,我有一大堆重复的任务要安排。他们查询数据库,找出该做什么,然后执行一些操作,如更新统计数据、发送电子邮件、获取文件和导入它们。目前,大概有十家,这个数字预计会增长很多。我没有任何时间限制,事实上,我的工作就是选择一种算法,这样就不会有人抱怨了D 目前,我正在使用线程和定期计划任务的临时组合,如 对于最重要的任务,有一个自己的线程在空闲时返回到短睡眠状态(当新的重要工作到来时,它可以从中被唤醒) 另一个重要任务在其自己的线程中每小时调度一次 定期安排中等重要性的任务来“填补漏洞”,因此在任何时候
- 对于最重要的任务,有一个自己的线程在空闲时返回到短睡眠状态(当新的重要工作到来时,它可以从中被唤醒)
- 另一个重要任务在其自己的线程中每小时调度一次
- 定期安排中等重要性的任务来“填补漏洞”,因此在任何时候可能只有一个任务在运行
- 最不重要的任务都由一个专用线程处理
- 由于最不重要任务的队列可能会大量增加,因此此类任务可能会无限期延迟
- 填补漏洞可能会出错,并且可能会同时运行许多任务
- 在任何给定时刻运行的任务数应取决于服务器负载。(*)
AbstractExecutionThreadService
s和AbstractScheduledService
s替换为如下工作方式:
- 无论发生什么情况,立即启动最高优先级的任务
- 仅当总负载为“小”时才启动中等优先级任务
- 仅在系统“大部分空闲”时启动最低优先级任务
- 使用提供的公式增加延迟任务的优先级
- 不要无谓地拖延重要任务
- 不要让太多并发运行的任务过多地降低服务器的速度
没有硬性的截止日期,也没有必要最小化使用的线程数量。我并不坚持要一个解决方案完全按照我所描述的那样去做,我不是在寻找一个库(我也不坚持要重新发明轮子)。我认为类似cron的调度器不是正确的解决方案。我认为您的计划与您想要的非常接近,可能只需要一点鼓励/批准/鼓励 我的想法是“如果我知道我可以运行的并发线程的最大数量,那么我将如何在3个线程队列中共享这些线程” 一旦我知道了这一点,我就可以设置3个队列,每个队列都有不同的可用线程份额。 -优先级1(最高)获得50%的工作 -优先级2得到35%的工作
-优先级3(最低)获得15%的工作使用
执行器服务
模型,重新排序执行器任务的经典解决方案是创建线程池执行器
,并使用优先级阻塞队列
为其提供任务-如前所述
然而,同样需要安排任务也会让事情变得复杂ScheduledThreadPoolExecutor
使用内部自定义BlockingQueue
在计划就绪时输入任务,但我认为您很清楚,它不容易进行进一步的自定义
乍一看,DelayQueue
看起来非常适合这项任务——它可以为下一个Delayed
元素或任务确定优先级。这将通过Delayed.getDelay()
处理关于是否准备就绪的延迟决策
此计划的美中不足之处在于,您试图将类似于
DelayQueue
的内容传递给ThreadPoolExecutor
的构造函数。这只接受BlockingQueue
,而不接受BlockingQueue虽然这个问题确实很有趣,但我怀疑这种格式是否适合StackOverflow。我是从眼睛的角度说这句话的,绝不是屈尊于一个拥有丰富经验的用户,从他的声誉来看,他应该比问一个尽管你很好,但没有人能以非自以为是的方式回答的问题更清楚(但抽象为“无代码”)和有趣的问题描述。说了这句话,并试图表现出善意,你看了吗?在这个网站上,你还可以找到一本关于基本概念和常见问题的食谱。我从来没有使用过它,但它可能会帮助您完成“不要再发明轮子”部分,并可能让您集中精力正确地获取调度参数。@kriegaex当然,我使用过。它有很多有用的特性,但它们似乎与我想要的是正交的。我列出的两个相互竞争的目标似乎没有通过谷歌搜索得到实现<代码>++
事实上,我的大部分问题只是上下文。我想,这就是为什么它听起来很模糊。通过定义一个目标函数,可以很容易地确定列出的目标,然后我们将得到一个优化问题。您刚才描述了为什么这个问题不适合这样。谢谢你用粗体字突出显示。但无论如何,祝你好运,这只是反馈,没有冒犯的意思。我要离开这里了。@kriegaex,恐怕我跟不上。是一个我没有精确描述的问题,还是一个优化问题?关于
public class BlockingDelayQueue extends AbstractQueue<Runnable>
implements BlockingQueue<Runnable> {
private final DelayQueue<DelayedRunnable> delayQueue;
public BlockingDelayQueue(DelayQueue<DelayedRunnable> delayQueue) {
this.delayQueue = delayQueue;
}
@Override
public boolean isEmpty() {
return delayQueue.isEmpty();
}
@Override
public Runnable poll(long timeout, TimeUnit unit)
throws InterruptedException {
DelayedRunnable delayedRunnable = delayQueue.poll(timeout, unit);
if (delayedRunnable == null)
return null;
return delayedRunnable.getCommand();
}
...
}
LOW {
boolean isReady(ThreadPoolExecutor executor) {
return executor.getActiveCount() == 0;
}
},
MEDIUM {
boolean isReady(ThreadPoolExecutor executor) {
return executor.getActiveCount() <= 1;
}
},
HIGH {
boolean isReady(ThreadPoolExecutor executor) {
return true;
}
};
@Override
public long getDelay(TimeUnit unit) {
long millis;
if (!priority.isReady(executor))
millis = 1000;
else
millis = time - System.currentTimeMillis();
return unit.convert(millis, TimeUnit.MILLISECONDS);
}
DelayedScheduler scheduler = new DelayedScheduler();
scheduler.schedule(task("Low 1"), 1, TimeUnit.SECONDS, Priority.LOW);
scheduler.schedule(task("Low 2"), 2, TimeUnit.SECONDS, Priority.LOW);
scheduler.schedule(task("Low 3"), 3, TimeUnit.SECONDS, Priority.LOW);
scheduler.schedule(task("Medium 1"), 1, TimeUnit.SECONDS, Priority.MEDIUM);
scheduler.schedule(task("Medium 2"), 2, TimeUnit.SECONDS, Priority.MEDIUM);
scheduler.schedule(task("Medium 3"), 3, TimeUnit.SECONDS, Priority.MEDIUM);
scheduler.schedule(task("High 1"), 1, TimeUnit.SECONDS, Priority.HIGH);
scheduler.schedule(task("High 2"), 2, TimeUnit.SECONDS, Priority.HIGH);
scheduler.schedule(task("High 3"), 3, TimeUnit.SECONDS, Priority.HIGH);
High 1 started at 1087ms
Medium 1 started at 1087ms
High 2 started at 2087ms
Medium 1 ended at 3087ms
High 1 ended at 3087ms
High 3 started at 3087ms
High 2 ended at 4088ms
Medium 2 started at 4088ms
High 3 ended at 5088ms
Medium 3 started at 5088ms
Medium 2 ended at 6088ms
Medium 3 ended at 7089ms
Low 1 started at 7089ms
Low 1 ended at 9089ms
Low 2 started at 9089ms
Low 2 ended at 11089ms
Low 3 started at 11089ms
Low 3 ended at 13089ms