Управление параллелизмом и вложенными параллельными коллекциями scala
Мне очень трудно понять это поведение параллельных коллекций в Scala.
import java.util.concurrent.TimeUnit
import scala.collection.parallel.ForkJoinTaskSupport
object test extends App {
val CHANGE_ME = false
val externalParallelism = if (CHANGE_ME) 10 else 2
val l = (1 until 100).par
val l2 = List(1).par // par but with only one element
l2.tasksupport = new ForkJoinTaskSupport(
new scala.concurrent.forkjoin.ForkJoinPool(externalParallelism))
l.tasksupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(2))
l2.map { j =>
l.map { i =>
println(s"STARTED $i")
TimeUnit.SECONDS.sleep(10) // blocking
println(s"DONE $i")
}
}
}
Если приведенный выше код запускается с CHANGE_ME = false, вы увидите
STARTED 1
STARTED 50
показывая, что текущий параллелизм равен 2, и это правильно, поскольку внутренняя параллельная коллекция l связана с поддержкой задач с помощью пула потоков fork-join с параллелизмом 2. Если сейчас вы установите CHANGE_ME = true, вы будете удивительно наблюдать
STARTED 87
STARTED 93
STARTED 13
STARTED 25
STARTED 75
STARTED 56
STARTED 62
STARTED 50
STARTED 1
свидетельство того, что внутренняя параллельная коллекция использует потоки, которые должны быть связаны с внешней параллельной коллекцией. Это ожидаемое поведение? Как тогда может быть связан параллелизм l?