scala.actors._
abstract class Future
Прежде всего, давайте посмотрим, что написано в документации:
Функция арности 0, возвращающая значение типа T, которое при применении блокирует текущего актера (Actor.self) до тех пор, пока не будет доступно будущее значение.
И это в основном все, что есть. Если вы общаетесь с субъектом из любого места за пределами другого участника (который может получать асинхронные ответы на сообщения просто с другим сообщением, используя ссылку sender
) и вам нужен ответ на отправленное сообщение, у вас есть два варианта:
- Отправить блокирующее сообщение, которое ждет, пока Актер не завершит вычисление вашего результата
- Отправьте сообщение, используя метод, который возвращает Future, и заблокируйте это Future, только если вам действительно нужно рассматриваемое значение (которое к тому времени уже могло быть вычислено)
Таким образом, Future - это плацдарм для значения, которое еще не существует, но, вероятно, появится в ближайшем будущем 1023 *. Интересно также следующее:
Можно запросить будущее, чтобы выяснить, доступно ли уже его значение без блокировки [с помощью «isSet»].
Это позволяет вам делать все, что вы хотите, пока нужное значение не будет вычислено / извлечено, и вы можете периодически проверять, стало ли значение доступным.
При копании в исходном коде библиотеки Scala я обнаружил, что Futures на самом деле просто актеры. Future
сам по себе является abstract class
, который расширяется на private class FutureActor
. Этот последний класс действительно реализует Future
-функцию.
object Futures
object Futures
далеко не так интересен, так как это всего лишь контейнер для "Методы, которые работают с фьючерсами" , удобный фабричный метод future
, который асинхронно оценивает переданный блок, возвращая будущее, представляющее результат. Вот небольшой пример:
import scala.actors.Futures
val f = Futures.future {
println("Start: inside block")
val s = System.currentTimeMillis
while(System.currentTimeMillis < (s + 1000)) {
// Simulate computation
}
println("Start: end of block")
42
}
println("After future")
println(f())
println("The end")
Что должно привести к чему-то вроде
Start: inside block
After future
Start: end of block
42
The end
Это показывает, что future
-call не блокирует следующий код, пока вы на самом деле не попытаетесь извлечь значение будущего (обратите внимание, что вывод недетерминирован . After future
также может появляются в начале вывода).
scala.collection.parallel
Этот пакет является новым для Scala 2.9.x и реализует параллельные аналоги для некоторых из наших любимых коллекций. Все они начинаются с Par
:
- ParIterable
- ParSeq
- PARSET
- ParMap
Как вы, возможно, уже знали или догадались, эти коллекции реализуют все возможные операции параллельно, не беспокоясь об этом. Небольшая демонстрация:
(1 to 10).par.map { b => print(b + " "); b * b }
3 1 6 2 7 4 5 9 10 8
# => (1, 4, 9, 16, 25, 36, 49, 64, 81, 100)
Результат всегда будет одинаковым, но порядок обработки элементов опять-таки недетерминирован. Кроме того, если вы работаете в многоядерной системе, вы, вероятно, ощутите хороший прирост производительности для больших коллекций.
trait FutureThreadPoolTasks
Черта FutureThreadPoolTasks
расширяет черту Tasks
, поэтому давайте сначала взглянем на нее. Комментарий выше черты говорит:
Черта, объявляющая возможности выполнения задач, используемые параллельными коллекциями.
Судя по комментариям других источников и методам, описанным в признаке Tasks
, задача представляет собой единицу работы, которую необходимо вычислить. В зависимости от того, может ли проблема делиться дальше, и если доступно больше ресурсов, Задача может разделить Задачу дальше, создавая больше задач.
Теперь сама черта FutureThreadPoolTasks
- это просто способ вычисления задач, который использует класс java.util.concurrent.Future
для своей синхронизации, то есть не использует scala.actors.Future
! Из источника:
Реализация объектов задач на основе API пула потоков Java и синхронизации с использованием фьючерсов.
object FutureThreadPoolTasks
Еще раз не очень впечатляющий, просто объект-компаньон, содержащий несколько (фактически только три) служебных метода, которые использует черта FutureThreadPoolTasks
.
scala.concurrent
Документация по этим классам действительно плохая, и, по-видимому, существует очень немного (если я не нашел ни одного) примеров, демонстрирующих использование этих классов. Я обязательно постараюсь собрать больше информации и расширить этот раздел, как только смогу!
scala.parallel
trait Future
Похоже, что это "Работа в процессе", поскольку пакет scala.parallel
содержит только эту черту. Из того, что я могу сказать, это будет связано с реализацией Future
, которая не использует Actors
, но это всего лишь предположение. Подпись черты следующая
trait Future[@specialized +R] extends (() => R)
Я даже не собираюсь объяснять аннотацию @specialized или дисперсий (+ перед общим R-типом), но основная идея в этой особенности заключается в том, что Future - это функция, которая при выполнении возвращает значение (и для этого должна блокировать, если оно еще не вычислено).
Кроме того, внутри самой черты есть только два метода, apply
и isDone
. Я предполагаю, что isDone
, как и scala.actors.Future.isSet
, должен быть неблокирующим вызовом, чтобы увидеть, было ли вычислено значение, и метод apply
должен использоваться для фактического получения значения.