基于令牌提交延迟任务

时间:2013-04-06 14:51:26

标签: java multithreading guava callable

人。我有一个任务我无法解决,因为我对多线程很新。我想编写一个维护以下语义的类:

interface TokenAwareTaskExecutor(){
   //Callable<Long> returns the time the task finishes.
   public void submitTask(String token, Callable<Long> task);
   public long getDelay();
}

在提交任务时,如果先前的调用添加了此类令牌,​​则服务会查找。如果是这样,则应在延迟之后以及在执行具有相同令牌的任何其他提交任务之后提交任务。如果没有这样的令牌,请添加它并立即提交任务。总而言之,我想实现一种负载均衡策略,允许独立处理具有给定频率的唯一令牌。你能指导我看一下吗?

2 个答案:

答案 0 :(得分:0)

如果没有太多不同的令牌,一种解决方案可能是将每个令牌映射到ScheduledThreadPoolExecutor的实例。然后,如果在地图中找到执行程序,则使用延迟计划任务。否则,请立即创建一个新的execotur并安排。

另一种方法是只有一个ScheduledThreadPoolExecutor和一个映射映射令牌到一个ScheduleInfo对象,该对象由一个原子计数器组成,该计数器计算该令牌等待的任务数量以及该令牌的调度时间。该令牌的最后一项任务。计数器和时间的任何更改必须在串联时进行并同步。

我们将每个传入任务包装在一个外部Callable中,该调度使用synchronized中的enter()方法ScheduleInfo进行调度,从而递增计数器。如果计数器为零,我们会立即安排并将调度时间设置为当前时间。如果计数器大于零,我们将延迟添加到计划时间并计划该确切时间。

当内部任务完成时,外部任务必须再次递减计数器,这发生在synchronized中的另一个exit()方法ScheduleInfo中。我不确定如何解释延迟(在一个任务结束和下一个任务开始之间的调用时间之间的时间)。在后一种情况下,我们也必须在这里调整计划时间。同样,enterexit不能重叠,因此必须同步。

如果没有尝试任何代码,这是不可能的,所以我欢迎任何批评。

答案 1 :(得分:0)

实施将涉及以下事项:

  1. 需要存储已提交的令牌以及这些令牌请求的状态:为了实现这一点,我将创建一个内部类,其中包含令牌名称,上次请求的状态,提交时间和最后结束时间要求。我将使用ConcurrentHashmap将相应的字符串标记作为键存储,并将每个bean的实例存储为值,并且每当有请求进入时,我将使用synchronize block锁定此bean。

  2. 每次请求到来时,都会检查地图中是否存在令牌条目,如果不存在,则会创建条目并继续执行任务。如果条目存在,它将尝试锁定bean实例,这意味着如果已经对bean进行了锁定,那么它将等待。

  3. 一旦请求完成其工作,它将在释放锁之前更新其在相应bean中的状态。

  4. 以上2点基本上设置了一个freamork用于实现,你可以扩展这个以实现其他方面,如果多个请求超过2然后排队然后顺序[你可以使用fairnes锁],如果你想要在多个请求之间添加任何额外延迟,那么也可以完成