在Java中向线程池中添加新任务之前等待任务完成的最佳方法?

我想使用类似ThreadPoolExecutor的东西来管理在可用线程上运行一堆任务。 这些任务都是相同的类型,但处理不同的帐户。 这些帐户的新任务可以定期添加,我希望它能够检查并且不允许新任务开始,直到同一帐户的旧任务已经完成。 最好的方法是什么?

  1. 帐户“234”的任务已启动(通过ThreadPoolExecutor.execute())

  2. 帐户“238”的任务已启动(通过ThreadPoolExecutor.execute())

  3. 帐户“234”的新任务已创建但未添加执行,因为第一个“234”任务未完成(检查此问题的最佳方法是什么?)

  4. 帐户“238”的任务完成

  5. 帐户“238”的新任务启动(通过ThreadPoolExecutor.execute()),因为当前没有为该帐户运行

最好的方法是什么? 只需要在等待/睡眠()中检查Runnable中的某些检查变量,以便完成“234”的第一个任务吗? 或者有更好的解决方案吗?

毫无疑问,对这部分API有更多经验的人会有更好的想法,但这是我对这个主题的看法……

基本上,我从一个“运行”和“等待”队列开始。 “运行”队列跟踪当前正在运行的内容,“等待”队列跟踪您阻止的任务。 这些队列需要键入某种“组标识符”以便于查找(例如Map ),例如,您的帐号

我会看一下覆盖execute方法。 在这里,我将传入的任务与正在运行的队列进行比较,以确定当前是否有任何相关任务正在运行。 如果有,我会将新任务放入等待队列。

然后我会覆盖beforeExecute方法。 在这里,我将在“运行”队列中注册任务。

我会覆盖’afterExecute’方法。 在这里,我将从“运行”队列中删除已完成的任务,查找等待任务的队列(通过已完成任务的组标识符),并通过execute方法将队列中的第一个任务添加到execute

或者你可以像路易斯建议的那样做:P

一个简单的可能性 也许过于简单。 创建10个SingleThreadedExecutors。 对于每项任务

  1. 通过使用accountID mod 10“hash”accountID来查找相应的SingleThreadedExecutor。 (实际上,accountID可能不是int,例如,如果它是一个String,则使用hashCode()mod 10)。
  2. 将任务提交给SingleThreadedExecutor。

这可能并不理想,因为帐户238的处理将被迫等到358完成,但至少你确定某个特定帐户(例如234)将永远不会同时运行。 取决于您可以允许的延迟时间。 显然,你可以使用Executors的数量和我所描述的简单化的“散列”algortihm。

我遇到了同样的问题。 我的解决方案是使用HashSet。

 private static HashSet runningTasks = new HashSet(); public void run(){ boolean isAlreadyRunning = false; synchronized (runningTasks) { if (runningTasks.contains(this.accountId)) { isAlreadyRunning = true; } else { runningTasks.add(this.accountId); } } if(isAlreadyRunning){ //schedule this task to run later here //what I did was to reinsert this task to the task queue 5 seconds later return; } //do your stuffs here synchronized (runningTasks) { runningTasks.remove(this.accountId); } }