YMMV:
scala> (1 to 10).par map println
1
6
2
3
4
7
5
8
9
这也是一个双核。。。
我认为如果你尝试足够多的跑步,你可能会看到不同的结果。以下是一段代码,显示了发生的一些情况:
import collection.parallel._
import collection.parallel.immutable._
class ParRangeEx(range: Range) extends ParRange(range) {
// Some minimal number of elements after which this collection
// should be handled sequentially by different processors.
override def threshold(sz: Int, p:Int) = {
val res = super.threshold(sz, p)
printf("threshold(%d, %d) returned %d
", sz, p, res)
res
}
override def splitter = {
new ParRangeIterator(range)
with SignalContextPassingIterator[ParRangeIterator] {
override def split: Seq[ParRangeIterator] = {
val res = super.split
println("split " + res) // probably doesn t show further splits
res
}
}
}
}
new ParRangeEx((1 to 10)).par map println
有些运行是穿插处理,有些运行是顺序处理。它似乎把负载一分为二。如果您将返回的阈值数更改为11,您将看到工作负载永远不会被拆分。
底层的调度机制是基于fork-join和工作窃取的。请参阅下面的JSR166源代码以获得一些见解。这可能是驱动同一个线程是否会同时处理两个任务(因此看起来是连续的)或两个线程处理每个任务的原因。
以下是我电脑上的输出示例:
threshold(10, 2) returned 1
split List(ParRangeIterator(over: Range(1, 2, 3, 4, 5)),
ParRangeIterator(over: Range(6, 7, 8, 9, 10)))
threshold(10, 2) returned 1
threshold(10, 2) returned 1
threshold(10, 2) returned 1
threshold(10, 2) returned 1
threshold(10, 2) returned 1
6
7
threshold(10, 2) returned 1
8
1
9
2
10
3
4
5