Spec-Zone.ru › Scala 2.12 Library

Пакет scala.concurrent

пакет concurrent

Этот пакет содержит базовые элементы для конкурентного и параллельного программирования.

Руководство

Более подробное руководство по Future и Promise, включая обсуждение и примеры, можно найти по адресу http://docs.scala-lang.org/overviews/core/futures.html.

Общие импорты

При работе с Future часто удобно импортировать весь пакет concurrent:

import scala.concurrent._

При использовании таких элементов, как Futures, часто необходимо наличие неявного ExecutionContext. Общие рекомендации по этим неявным параметрам следующие.

Если код представляет собой определение класса или метода, и неявный ExecutionContext не доступен, запросите его у вызывающей стороны, добавив список неявных параметров:

def myMethod(myParam: MyType)(implicit ec: ExecutionContext) = …
//Or
class MyClass(myParam: MyType)(implicit ec: ExecutionContext) { … }

Это позволяет вызывающей стороне метода или создателю экземпляра класса решить, какой ExecutionContext следует использовать.

Для типичного использования REPL и экспериментов часто желательно импортировать глобальный ExecutionContext.

import scala.concurrent.ExcutionContext.Implicits.global

Указание продолжительности

Операции часто требуют указания продолжительности. Доступен DSL для продолжительности, чтобы упростить их определение:

import scala.concurrent.duration._
val d: Duration = 10.seconds

Использование Future для асинхронного вычисления

Базовое использование Future простое с помощью фабричного метода на Future, который асинхронно выполняет предоставленную функцию, возвращая будущий результат этой функции без блокировки текущей нити. Для создания Future вам потребуется либо неявный, либо явный ExecutionContext:

import scala.concurrent._
import ExecutionContext.Implicits.global  // implicit execution context

val firstZebra: Future[Int] = Future {
  val source = scala.io.Source.fromFile("/etc/dictionaries-common/words")
  source.toSeq.indexOfSlice("zebra")
}

Избегайте блокировки

Хотя блокировка возможна для ожидания результатов (с обязательным временем ожидания):

import scala.concurrent.duration._
Await.result(firstZebra, 10.seconds)

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

val animalRange: Future[Int] = for {
  aardvark <- firstAardvark
  zebra <- firstZebra
} yield zebra - aardvark

animalRange.onSuccess {
  case x if x > 500000 => println("It's a long way from Aardvark to Zebra")
}
Источник
package.scala
Линейные надтипы

Члены типов

тракт Awaitable[+T] extends AnyRef

Объект, который, в конечном итоге, может быть завершён значением типа T , которое можно ожидать с помощью методов блокирования.

Объект Await предоставляет методы, позволяющие получить результат Awaitable, блокируя текущий поток до завершения Awaitable или наступления таймаута.

тракт BlockContext extends AnyRef

Контекст, о котором scala.concurrent.blocking оповещает, когда поток собирается заблокироваться. Фактически, этот тракт предоставляет реализацию для scala.concurrent.Await. scala.concurrent.Await.result() и scala.concurrent.Await.ready() находит экземпляр BlockContext, сначала проверив, был ли он предоставлен через BlockContext.withBlockContext(), а если нет, то проверив, является ли Thread.currentThread экземпляром BlockContext. Таким образом, пул потоков может иметь свои экземпляры java.lang.Thread, реализующие BlockContext. Использованный по умолчанию BlockContext используется, если поток не реализует BlockContext.

Как правило, вы захотите подключиться к предыдущему BlockContext, как в этом примере:

val oldContext = BlockContext.current
val myContext = new BlockContext {
  override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = {
    // you'd have code here doing whatever you need to do
    // when the thread is about to block.
    // Then you'd chain to the previous context:
    oldContext.blockOn(thunk)
  }
}
BlockContext.withBlockContext(myContext) {
  // then this block runs with myContext as the handler
  // for scala.concurrent.blocking
}

sealed тракт CanAwait extends AnyRef

Этот маркерный тракт используется Await для гарантии того, что Awaitable.ready и Awaitable.result не вызываются напрямую кодом пользователя. Неявный экземпляр этого тракта доступен только когда код пользователя в настоящее время вызывает методы объекта Await.

Аннотации
@implicitNotFound( msg = ... )

тип CancellationException = java.util.concurrent.CancellationException

класс Channel[A] extends AnyRef

Этот класс предоставляет простую очередь FIFO объектов данных, которые считываются одним или несколькими потоками чтения.

A

тип обмениваемых данных

класс DelayedLazyVal[T] extends AnyRef

DelayedLazyVal — это обёртка для длительных вычислений, имеющих валидный частично вычисленный результат.

Первый аргумент — функция получения результата в любой момент времени, а второй — длительное вычисление. После завершения вычисления метод apply перестанет перевычислять его и вернёт фиксированное значение с этого момента.

С момента

2.8

тракт ExecutionContext extends AnyRef

ExecutionContext может асинхронно выполнять логику программы, обычно, но не обязательно, в пуле потоков.

Универсальный ExecutionContext должен быть асинхронным при выполнении любого Runnable , переданного в метод execute. Специализированный ExecutionContext может быть синхронным, но должен передаваться только в код, который явно безопасен для выполнения с использованием синхронного ExecutionContext.

API, такие как Future.onComplete, требуют, чтобы вы предоставили обратный вызов и неявный ExecutionContext. Неявный ExecutionContext будет использован для выполнения обратного вызова.

Хотя можно просто импортировать scala.concurrent.ExecutionContext.Implicits.global для получения неявного ExecutionContext, разработчики приложений должны тщательно обдумать, где они хотят установить политику выполнения; в идеале, в одном месте в приложении (или в логически связанной части кода) должно приниматься решение о том, какой ExecutionContext использовать. То есть, в основном следует избегать жёсткого кодирования, особенно посредством импорта, scala.concurrent.ExecutionContext.Implicits.global. Рекомендуемый подход — добавить (implicit ec: ExecutionContext) к методам или параметрам конструктора класса, которым нужен ExecutionContext.

Затем локально импортируйте конкретный ExecutionContext в одном месте для всего приложения или модуля, неявно передавая его в отдельные методы. В качестве альтернативы, определите локальный неявный val с необходимым ExecutionContext.

Может быть уместно создать пользовательский ExecutionContext для выполнения кода, который блокируется при вводе-выводе или выполняет длительные вычисления. ExecutionContext.fromExecutorService и ExecutionContext.fromExecutor — хорошие способы создания пользовательского ExecutionContext.

Целью ExecutionContext является лексическое ограничение выполнения кода. То есть каждый метод, класс, файл, пакет или приложение определяет, как выполнять свой собственный код. Это позволяет избежать проблем, таких как выполнение обратных вызовов приложения в пуле потоков, принадлежащем библиотеке для работы с сетью. Размеры пула потоков библиотеки для работы с сетью можно безопасно настроить, зная, что на них будут влиять только сетевые операции этой библиотеки. Выполнение обратных вызовов приложения можно настроить отдельно.

Аннотации
@implicitNotFound( msg = ... )

тракт ExecutionContextExecutor extends ExecutionContext with Executor

тракт ExecutionContextExecutorService extends ExecutionContextExecutor with ExecutorService

тип ExecutionException = java.util.concurrent.ExecutionException

тракт Future[+T] extends Awaitable[T]

A Future представляет значение, которое может или не может *в данный момент* быть доступно, но будет доступно в какой-то момент, или исключение, если это значение не может быть сделано доступным.

Асинхронные вычисления, которые возвращают значения типа Future, создаются с помощью вызова Future.apply и вычисляются с использованием предоставленного ExecutionContext, который может быть поддерживаемым пулом потоков.

import ExecutionContext.Implicits.global
val s = "Hello"
val f: Future[String] = Future {
  s + " future!"
}
f foreach {
  msg => println(msg)
}
См. также

Futures и Promises

trait OnCompleteRunnable extends AnyRef

Маркер, указывающий, что java.lang.Runnable, предоставленный scala.concurrent.ExecutionContext, оборачивает обратный вызов, предоставленный Future.onComplete. Все обратные вызовы, предоставленные Future, в конечном итоге проходят через onComplete, поэтому это позволяет ExecutionContext специально обрабатывать обратные вызовы, которые были выполнены Future, если это необходимо.

trait Promise[T] extends AnyRef

class SyncChannel[A] extends AnyRef

SyncChannel позволяет синхронно обмениваться данными между потоком чтения и потоком записи. Поток записи блокируется до тех пор, пока данные, подлежащие записи, не будут прочитаны соответствующим потоком чтения.

С момента

2.0

class SyncVar[A] extends AnyRef

Класс для обеспечения безопасного конкуретного доступа к изменяемой ячейке. Все методы синхронизированы.

A

тип содержащегося значения

type TimeoutException = java.util.concurrent.TimeoutException

class Lock extends AnyRef

Этот класс ...

Аннотации
@deprecated
Устарело

(С версии 2.11.2) используйте java.util.concurrent.locks.Lock

Члены значений

def blocking[T](body: ⇒ T): T

Используется для обозначения фрагмента кода, который потенциально блокирует, позволяя текущему BlockContext настраивать поведение среды выполнения. Правильное помечание блокирующего кода может улучшить производительность или предотвратить тупики.

Блокировка на Awaitable должна выполняться с использованием Await.result вместо blocking.

body

Фрагмент кода, который содержит потенциально блокирующие или длительные вызовы.

Аннотации
@throws( clazz = classOf[Exception] )
Исключения

CancellationException если вычисление было отменено

InterruptedException в случае прерывания ожидания в рамках блокирующего body

object Await

Await используется для обеспечения надлежащей обработки блокировки для экземпляров Awaitable.

Хотя иногда полезно, например, для тестирования, рекомендуется по возможности избегать Await — вместо этого предпочтительнее использовать комбинаторы и/или обратные вызовы. Методы Await's result и ready блокируют выполнение вызывающего потока до тех пор, пока они не вернутся, что приведет к снижению производительности и, возможно, проблемам тупика.

object BlockContext

object ExecutionContext

object Future

object JavaConversions

object Promise

© 2002-2019 EPFL, with contributions from Lightbend.
Licensed under the Apache License, Version 2.0.
https://www.scala-lang.org/api/2.12.9/scala/concurrent/index.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API