2016-10-11 11 views
2

У меня есть набор задач Scalaz. Создано вот так:Как запускать задачи Scalaz параллельно

val tasks = for (i <- 1 to 50) yield { 
    Task.delay({ 
    Thread.sleep(100L) 
    println(i) 
    i 
    }) 
} 

val r = Nondeterminism[Task].gatherUnordered(tasks).run 
println(r.mkString(" ")) 

Я ожидал бы, что задачи будут выполняться параллельно. Чтобы печатать цифры в произвольном порядке и не принимать 5 секунд (в каждой из них 50 задач и 100 миллисекундов).

Однако ясно, что каждая задача занимает 100 миллисекунд, все они занимают 5 секунд и упорядоченный список упорядочен.

Как запустить их параллельно? Где Task выполняет поток для запуска?

ответ

3

Task.delay приостанавливает оценку своих аргументов, но в нем ничего не говорится о том, где будет проводиться оценка. Вы хотите Task.apply, которая имеет ту же сигнатуру, за исключением того, что он принимает неявное ExecutorService, который будет решать, какой поток оценка будет происходить в:

import scalaz.Nondeterminism, scalaz.concurrent.Task 

val tasks = for (i <- 1 to 50) yield { 
    Task { 
    Thread.sleep(100L) 
    println(i) 
    i 
    } 
} 

val r = Nondeterminism[Task].gatherUnordered(tasks).run 
println(r.mkString(" ")) 

Это будет использовать по умолчанию ExecutorService, который оборачивает фиксированный пул потоков. Если вам нужна другая стратегия, вы можете либо поместить другой ExecutorService в неявную область, либо указать один из них во втором списке аргументов для Task.apply.