Jof*_*fer 4 concurrency scala blocking
参考这个被接受的答案中的第三点,是否有任何情况下,blocking对于长时间运行的计算,无论是CPU还是IO绑定,在"a"内执行它都是毫无意义或不好的Future?
从我的实践来看,如果要处理大量消息并且每个消息需要长时间阻塞(这也意味着它在此期间保留了一些内存),blocking + ForkJoinPool可能会导致线程的连续和无法控制的创建.ForkJoinPool创建新线程以补偿"可管理被阻止"的线程,无论如何MaxThreadCount; 向VisualVm中的数百个线程问好.它几乎可以杀死背压,因为在游泳池的队列中总是有一个任务地点(如果你的背压基于 ThreadPoolExecutor政策).新线程分配和垃圾收集都会破坏性能.
所以:
blocking{}(没有锁定)期间实际使用你的CPU是没有意义的,因为它只会增加线程数量而不是系统中真实核心的数量.PS blocking隐藏在里面Await.result,所以它并不总是很明显.在我们的项目中,有人Await在一些潜在的工作者中做了这样的事
这取决于ExecutionContext您Future正在执行的操作。
无意义:
如果ExecutionContext不是 a BlockContext,则使用blocking将毫无意义。也就是说,它将使用DefaultBlockContext,它只执行代码而无需任何特殊处理。它可能不会增加那么多开销,但仍然毫无意义。
坏的:
当线程池即将耗尽时,ScalaExecutionContext.Implicits.global会在 a 中生成新线程ForkJoinPool。也就是说,如果它知道这将通过blocking. 如果您生成大量线程,这可能很糟糕。如果您要在短时间内排队大量工作,global上下文会很高兴地扩展,直到陷入僵局。@dk14 的回答更深入地解释了这一点,但要点是它可能是一个性能杀手,因为托管阻塞实际上很快就会变得无法管理。
的主要目的blocking是避免线程池内的死锁,因此在达到死锁比产生更多线程更糟糕的意义上,它与性能密切相关。但是,它绝对不是神奇的性能增强器。
我blocking在这个答案中特别写了更多。
| 归档时间: |
|
| 查看次数: |
539 次 |
| 最近记录: |