Threadpool死锁:设计反对或检测

时间:2015-02-04 19:24:54

标签: java threadpool deadlock

我希望这不是过分广泛;我的问题是"我如何使用多个Threadpool设计一个不能自行解锁的服务?"。

我拥有一个Web服务,可以在单个用户请求中扇出100个线程,以低延迟执行数据聚合。在我的服务中有许多ExecutorServices包装固定线程池,我需要帮助解决一个有趣的方法,这可能会造成死锁。

我有一个线程池A,用于保存发出网络请求的线程,还有另一个线程池B,用于保存他们拥有的"拥有"线程;业务逻辑的聚合位可能会散布到少数请求中。此外,B中的线程偶尔会向线程池B提交一些工作,这可以通过聚合3个更简单的子聚合来完成聚合。

这种模式就是问题所在。让我们考虑一种提交给x的请求风格B,这会导致将额外请求x'提交给B。我们还要考虑B是一个包含50个线程的固定线程池。当类型x的50个请求同时进入时,B中的所有线程都用于处理这些请求。所有这些都将x1提交给B,它位于队列中等待一个帖子。然后,所有请求的所有处理都处于死锁状态60秒,直到达到超时并且x请求都返回异常。

我考虑/尝试过的事情:

  • 调整数字。可以连接的最大用户数为50,B中的线程数为100.防止出现问题,但看起来像是一个黑客攻击,当另一个开发人员在一年内调整不相关的数字而没有人能弄清楚为什么我们锁定一次一周负荷。我想在设计中解决这个问题。
  • BB'提交了一个新的线程池。不行,因为这种扇出可能会有多个步骤(我创建B''B''',......?)
  • B没有最大线程。可能接受,似乎很危险。
  • 另一个模型(更多回调?)线程不提交并等待相同的工作单元;相反,他们提交工作并提交回复"进入 "运行后"池。这样,没有什么可以等待自己的池中的东西。是先例,这是个好主意吗?
  • 将所有线程池折叠在一起并删除max?

1 个答案:

答案 0 :(得分:2)

你的“更多回调”答案似乎主要通过Java 8中的CompletionStage API解决 - 缺少“runAfterAllAsync”方法意味着你可能需要做一些外部工作才能获得在你的3个子任务组之后发生的事情,但这是我开始看的地方。 This tutorial有一个可能有所帮助的例子。