【问题标题】:"Routing" tasks inside threadpoolexecutor线程池执行器中的“路由”任务
【发布时间】:2013-07-22 12:33:58
【问题描述】:

我有一个实现 Runnable 的类

public class MyRunnable implements Runnable {
    private long RID = <SOME_LONG_ID_VALUE>;
    public long getRID() { return this.RID; }
    public void run {
        System.out.println("HAI!");
    }
}

有没有办法通过RID 字段“路由”ThreadPoolExecutor 内的任务(我的意思是,如果线程 N 3 使用 RID = 1 运行 Runnable,那么使用 RID = 1 的下一次测试必须由线程 N 3 执行(如果它还活着)) 谢谢。

【问题讨论】:

  • 这样做的目的是什么?我没有看到。可能有很多情况,如果 N 3 很忙或者它不再存在等等。
  • 简而言之 - 目的是避免竞争条件并使用相同的 RID 执行 MyRunnables,以便将它们提交给 ThreadPoolExecutor。
  • 关于案例,如上所述:如果线程 N3 不存在不再存在,ThreadPoolExecutor 必须创建新线程,“id”为 3。如果线程忙,则必须在线程空闲之前执行此任务.

标签: java multithreading threadpool threadpoolexecutor


【解决方案1】:

好吧,我认为避免竞争条件(如您的 cmets 中所述)不会有任何帮助。待办事项:

如果线程 N3 不再存在,ThreadPoolExecutor 必须创建新线程,“id”为 3。如果线程忙,则必须等到线程空闲后才能执行此任务

ThreadPoolExecutor 为您进行线程管理。要做到以上,用现有的库是不可能的,你可能必须创建自己的库来做到这一点。如果您的逻辑和线程安全性依赖于RID,那么我宁愿推荐使用 RID 和 ReentrantLock 的 Map,如下所示:

ConcurrentHashMap<Long, ReentrantLock> map = new ConcurrentHashMap<Long, ReentrantLock>();

public synchornized ReentrantLock getLock(Long id){
    ReentrantLock lock = map.get(id);
    if(lock!=null)
       return lock;
    else{
       map.put(id, new ReentrantLock());
 }

在您的Runnable 中,您可以将lock 设置为所需的值并进行相应的同步。

恕我直言,使用线程池的线程 ID 进行同步是一个非常糟糕的主意。生活多次可以简单得多。

【讨论】:

    【解决方案2】:

    据我了解,对于每个 RID,您都有一个执行上下文,并且您希望针对该上下文连续执行所有 MyRunnable 对象。

    您的错误是您尝试将该上下文链接到一个线程。更好地由 Actor 表示该上下文。您可以使用广为人知的 Actor 框架,例如 Akka,但为了您的目的,简单的 Actor implementation 就可以了。

    编辑: 另一种观点:由于Actor实现有唯一的接口方法execute,所以可以认为是一个串行执行器,串行运行提交的任务。并且由于它没有自己的线程池,而是使用另一个执行器,在所有 Actor 之间共享,因此可以称为辅助执行器。

    【讨论】:

    • 并非如此。主要目标是严格按照添加到 ThreadPoolExecutor 的顺序运行 MyRunnables(不是并行的,在一个线程中)。它们应该严格按顺序运行。
    • 好的,那么上下文无非是一个命令。然而,这个顺序必须有它的表示,推荐的 Actor 实现看起来已经足够好了。换句话说,该 Actor 实现可以称为辅助执行器,请参阅编辑后的答案。
    【解决方案3】:

    使用一组执行器服务,每个服务运行一个线程。然后根据 ID 的模数%(假设它是 long/int 的原始 ID 或哈希码)相对于某个所需的最大大小分配任务,并将该结果用作新 ID,这样您就可以拥有在以过多的执行器服务对象结束与在处理中仍获得大量并发之间取得平衡。

    来自 h22 的回答的原始想法:Thread pool that binds tasks for a given ID to the same thread

    【讨论】:

      猜你喜欢
      • 2019-10-08
      • 2011-11-03
      • 1970-01-01
      • 2014-06-14
      • 1970-01-01
      • 2021-05-17
      • 2015-06-26
      • 2017-04-28
      • 2014-08-27
      相关资源
      最近更新 更多