2013-03-11 47 views
0

我注意到,自从Scala 2.9。*以来,setMaximumPoolSize方法似乎从ForkJoinPool消失了,它看起来像是我想要的。大多数关于限制Scala平行集合中并行性的讨论围绕着同一个类的setParallelism方法(它也消失了,但对我来说不是那么严重),但在我的情况下,并行任务可以执行外部IO,并且经常会阻止它。 ForkJoinPool然后在这种情况下启动更多的线程,并有效地执行针对有问题的共享IO资源的DOS,这是不可取的。Replacement for setMaximumPoolSize on ForkJoinPool

有没有办法以某种方式限制池中的线程数?我并不在乎IO产生的行为,但我想要一定程度的并行性,因为我的IO任务是独立的,不会互相干扰。

回答

1

您引用的行为称为“延续线程”。由于join()方法不会执行上下文切换,因此框架将在没有这些附加线程的情况下停止。已经有数百/数千个这些额外线程产生的报道。

Java8用“延续线程”代替了这种可怕的做法。也就是说,线程继续从双端队列中获取任务,但可能导致失速或堆栈溢出。没有替代使用ForkJoinPool.managedBlock()的代码,这可能是您处于I/O的位置。

+0

Java8之前有什么可做的吗?据我了解,Scala的'ForkJoinPool'是java代码的副本,可以避免依赖于更新的JRE而不愿意依赖它,但是我不认为当前的Scala版本有你提到的那些延续线程。我的目标是避免获得数千个并发IO线程,并且我并不介意我如何到达那里。 – 2013-03-12 13:50:24

+0

不是我所知道的。目前的Scala版本基于旧版本的jsr166代码。该版本使用“延续线程”,这就是为什么你得到所有这些额外的线程。问题总是归结为“当线程需要发出wait()时如何释放线程”唯一正确的答案是框架无法执行的上下文切换。 – edharned 2013-03-12 14:19:05

+0

嘘! :(噢,谢谢澄清情况! – 2013-03-12 14:41:46