我们遇到了一些问题。 :)将ExecutorService与任务树结合使用
我们希望确保只有N个线程随时都在执行后台任务。为此,我们使用了一个固定的线程池执行器。它似乎工作正常。
然后我们发现了一个问题。假设你有一个类,它使用执行器来做一些并行工作,然后在执行器线程中调用其他一些类,同时也执行一些并行工作,并打算等待它。这里发生了什么:
- 主线程调用第一级方法。
- 该方法认为它可以并行化为16个任务并分解其工作。
- 将16个任务提交给执行者。
- 主线程开始等待其任务完成。
- 假设有四个线程可用,前四个任务每个都被拾取并运行。所以队列中剩下12个任务。
- 现在,其中一个任务调用其他一些方法。
- 这种新方法认为它可以并行化为2个任务。我们假设这是并行合并排序的第一步,或者沿着这些方向。
- 2任务提交给执行者。
- 此线程现在开始等待其任务完成。
嗯。所以在这一点上,所有四个线程现在都将等待任务完成,但他们正在协作阻止执行程序实际运行这些任务。
此问题的解决方案1如下所示:在向执行程序提交新任务时,如果我们已经运行了所有线程,并且已经在其中一个执行程序线程上运行,请以内联方式运行任务。这工作正常10个月,但现在我们遇到了问题。如果它提交的新任务仍然比较大,那么您可以进入新任务阻止该方法将其他任务添加到队列的情况,否则这些任务可以被其他工作线程拾取。因此,当线程正在处理内联工作时,您会遇到巨大延迟。
是否有更好的解决方案来执行潜在的无界限后台任务树的核心问题?我知道.NET等同于执行器服务具有某种内置的能力,可以从队列中窃取,从而防止发生最初的死锁问题,而据我所知,这是一个理想的解决方案。但是在Java的土地上呢?
你们是否解决了你的问题?你在找什么答案? – 2011-03-15 15:24:12