2013-04-06 81 views
2

人与延迟提交任务。我有一个任务,因为我对多线程很陌生,所以我无法将自己的头围绕。我想写一类将维修器材以下语义:基于令牌

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

在提交任务,服务查找,如果这样的标记已经被以前调用添加。如果是这样,则应在延迟之后并且在执行了具有相同令牌的任何其他提交的任务之后提交任务。如果这种令牌不存在,请添加它并立即提交任务。总而言之,我想实现一个负载均衡策略,它允许独立处理给定频率的独特令牌。你能指导我看看什么吗?

回答

0

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

另一种方法是只生一个ScheduledThreadPoolExecutor和地图测绘令牌由计数如何为令牌许多任务都在等待一个原子计数器和一个调度时间与该令牌去年任务的ScheduleInfo对象。对计数器和时间的任何更改必须在串联中进行并进行同步。

我们将每个传入任务封装在外部Callable中,该帐户在调度时使用​​方法enter()ScheduleInfo进行计数。如果计数器为零,我们会毫不拖延地安排时间,并将计划时间设置为当前时间。如果计数器大于零,我们将延迟添加到确切时间的计划时间和计划。

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

这是从我的头,但不尝试任何代码,所以我欢迎任何批评。

+0

我不认为ScheduledThreadPoolExecutor可以实现这一点,没有固定的延迟,也不是一个可扩展的解决方案。 – Lokesh 2013-04-06 17:09:38

+0

好的,所以我给了它更多的想法:) – 2013-04-06 21:16:29

0

的实施将涉及以下几件事:

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

  2. 每次都会有请求将检查检查标记条目是否存在于地图中,如果不存在,它将创建一个条目并继续执行任务。如果条目存在,它将试图锁定bean实例,这意味着如果已经在bean上使用了锁定,那么它将等待。

  3. 一旦请求已经完成了它的任务,它会更新其在释放锁之前,相应的bean状态。

以上2点基本上建立了一个freamork执行,你可以扩展实现其他方面也一样,如果多个请求超过2出现,然后排队,然后按顺序[您可以使用fairnes锁定]如果你想在多个请求之间增加任何额外的延迟,那么也可以这样做