如何避免死锁和使用太多线程?

时间:2011-04-14 18:34:26

标签: java threadpool

使用Executors.newFixedThreadPool(int nThreads)是一种很好的方法来最小化创建太多线程的开销,但是如果所有线程都在等待另一个本身正在等待来自其中的空闲线程的作业,则可能导致死锁。池。有时问题可以通过使用多个线程池来解决,但有时却不能解决。我正在寻找类似于newFixedThreadPool的行为,除非所有池化线程都被阻塞 - 在这种情况下,尽管有预定义的绑定,池也应该增长。 有这样的东西吗?


实际上,僵局在这里并不重要。真正的问题是“如何管理运行线程”的数量,而不是它们的总数。在尝试保持CPU充分利用而不会产生不必要的多线程时,这也很有趣。

3 个答案:

答案 0 :(得分:4)

如果您遇到争用问题,则会出现设计问题。如果你想要如你所描述的那样快速修复,你只能治愈症状,而不是潜在的疾病。

您应该使用其他方法重构您的设计以消除死锁。

答案 1 :(得分:2)

将池中的线程阻塞等待同一线程池中的其他线程通常是个坏主意。

我会尝试将设计更改为非阻塞设计。如果一个线程需要同一个执行器正在处理的另一个操作的结果,我会让它将任务提交给执行程序,以便在第二个操作完成后运行。或者将一个对象放入一个队列中,以便在另一个作业完成后再获取。

或者,您可以执行Swing对模式对话框的操作,并让线程即将阻止启动子线程以保持处理请求,直到父线程解除阻塞。虽然这样做很棘手但是需要你手动管理线程,这比使用Executor要安全得多。

答案 2 :(得分:1)

Executor.newCachedThreadPool();缓存的线程池将检查是否有可用的线程。如果有,则线程池将重新使用该线程。如果不是,则线程池将创建一个新线程。线程的生存时间是60秒,因此60秒后额外的线程将被终止。