Ответ 1
scala.actors._
abstract class Future
Прежде всего, давайте посмотрим, что говорится в документации:
Функция arity 0, сохраняющая значение типа T, которое при применении блокирует текущий актер (Actor.self) до тех пор, пока не будет доступно будущее.
И это в основном все, что есть. Если вы общаетесь с Актером из любого места вне другого актера (который может получать асинхронные ответы на сообщения просто с другим сообщением, используя ссылку sender
), и вам нужен ответ на отправленное сообщение, у вас есть два варианта:
- Отправьте сообщение блокировки, которое ждет, пока актер не закончит вычислять ваш результат.
- Отправьте сообщение, используя метод, который возвращает "Будущее", и блокирует это Будущее только в том случае, если вам действительно нужно соответствующее значение (которое к тому времени могло быть вычислено).
Итак, будущее - это место для ценности, которая еще не существует, но, вероятно, будет в ближайшем будущем. Также интересно следующее:
Можно узнать будущее, чтобы узнать, доступно ли его значение без блокировки [с использованием "isSet" ].
Это позволяет делать все, что угодно, до тех пор, пока не будет вычислено/получено, и вы можете периодически проверять, стало ли это значение доступным.
Когда вы копаете бит в исходный код библиотеки Scala, я обнаружил, что Futures - это фактически актеры. Future
сам по себе является a abstract class
, который расширяется private class FutureActor
. Этот последний класс является тем, который фактически реализует Future
-функционал.
object Futures
object Futures
, безусловно, не так интересен, поскольку это всего лишь контейнер для "Методов, работающих на фьючерсах", удобный factory метод 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
Это похоже на "Работа в progess", поскольку пакет scala.parallel
содержит только этот признак. Из того, что я могу сказать, это будет связано с реализацией Future
, которая не использует Actors
, но это всего лишь предположение. Подпись признака следующая
trait Future[@specialized +R] extends (() => R)
Я даже не собираюсь объяснять аннотацию @specialized или отклонения (+ перед родовым типом R), но основная идея в этом признаке заключается в том, что Будущее - это функция, которая при выполнении возвращает значение (и должна блокироваться, если она еще не была вычислена)).
Кроме того, внутри самого признака есть только два метода: apply
и isDone
. Я предполагаю, что isDone
, как и scala.actors.Future.isSet
, должен быть неблокирующим вызовом, чтобы увидеть, было ли вычисляемое значение, и метод apply
должен использоваться для фактического получения значения.