Spec-Zone.ru › Scala 2.13 Library

Пакет scala.concurrent

пакет concurrent

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

Руководство

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

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

При работе с будущими (Futures) часто удобно импортировать весь пакет 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

Использование Futures для неблокирующих вычислений

Базовое использование будущих (futures) просто с помощью фабричного метода на 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 и параллельными вычислениями, чтобы избежать потенциальных тупиков и улучшить производительность. Вместо этого используйте обратные вызовы или комбинаторы, чтобы оставаться в области будущих (futures):

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
Линейные супертипы
AnyRef, Any

Члены пакета

пакет duration

Типовые члены

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

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

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

трайт Batchable extends AnyRef

трайт 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("Не вызывайте методы `Awaitable` напрямую, используйте объект `Await`.")

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

трайт ExecutionContext extends AnyRef

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

Объект общего назначения ExecutionContext должен быть асинхронным при выполнении любого действия, передаваемого в его метод 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("""Не найдено неявное ExecutionContext. Вы можете передать
параметр (implicit ec: ExecutionContext) в ваш метод.

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

Если ваше приложение не определяет ExecutionContext в другом месте,
рассмотрите возможность использования глобального ExecutionContext Scala
путем определения следующего:

implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global"""
)

трайт ExecutionContextExecutor extends ExecutionContext with Executor

трайт ExecutionContextExecutorService extends ExecutionContextExecutor with ExecutorService

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

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

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

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

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

Futures и Promises

описание Promise[T] extends AnyRef

Promise — это объект, который может быть завершен значением или провален исключением.

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

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

Члены-значения

final def blocking[T](body: => T): T

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

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

body

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

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

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

InterruptedException, если ожидание внутри блокирующего body было прервано

объект Await

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

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

объект BlockContext

объект ExecutionContext

объект Future

объект Promise

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

Spec-Zone.ru

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