Объект scala.concurrent.ExecutionContext
объект ExecutionContext
Содержит методы-фабрики для создания контекстов выполнения.
| Супертипы | |
|---|---|
| Тип самого объекта |
Классы-объекты
Исходный код
объект Implicits
Исходный код
объект parasitic extends ExecutionContextExecutor
ПРЕДУПРЕЖДЕНИЕ: Выполняйте только код, который быстро вернёт управление вызывающему методу.
Этот ExecutionContext забирает время выполнения у других потоков, выполняя свои Runnable в Thread, вызывая execute, а затем возвращая управление вызывающему методу после выполнения *всех* своих Runnable. Вложенные вызовы execute будут перепрыгивать, чтобы предотвратить неконтролируемый рост стека.
При использовании parasitic с абстракциями, такими как Future, в многих случаях будет непредсказуемо, какой Thread будет выполнять логику, так как это зависит от того, когда/если данный Future будет завершён.
Не вызывайте блокирующий код в Runnable методах, переданных в этот ExecutionContext, так как это помешает прогрессу других ожидающих Runnable и вызывающему Thread.
Симптомы неправильного использования этого ExecutionContext включают, но не ограничиваются, тупиками и серьёзными проблемами производительности.
Любые NonFatal или InterruptedException будут сообщены defaultReporter.
Конкретные методы
Исходный код
Создаёт ExecutionContext из данного Executor.
| Параметры |
|
|---|---|
| Возвращает |
|
Исходный код
Создаёт ExecutionContext из данного Executor с стандартным отчётом об ошибках.
| Параметры |
|
|---|---|
| Возвращает |
|
Исходный код
def fromExecutorService(e: ExecutorService, reporter: Throwable => Unit): ExecutionContextExecutorService
Создаёт ExecutionContext из данного ExecutorService.
| Параметры значения |
|
|---|---|
| Возвращает |
|
Исходный код
Создаёт ExecutionContext из заданного ExecutorService с отчётностью по умолчанию.
Если гарантируется, что ни одна из выполняемых задач не блокируется, для создания ExecutionContext можно использовать однопоточное ExecutorService следующим образом:
import java.util.concurrent.Executors val ec = ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor())
| Параметры значения |
|
|---|---|
| Возвращает |
|
Конкретные поля
Исходный код
Отчётность по умолчанию просто выводит трассировку стека Throwable в System.err.
| Возвращает | функцию для отчётности об ошибках |
|---|
Исходный код
final lazy val global: ExecutionContextExecutor
Глобальный ExecutionContext. Эта реализация ExecutionContext по умолчанию поддерживается пулом потоков с воровством задач. Её можно настроить с помощью следующих системных свойств:
scala.concurrent.context.minThreads= по умолчанию "1"scala.concurrent.context.numThreads= по умолчанию "x1" (то есть текущее количество доступных процессоров * 1)scala.concurrent.context.maxThreads= по умолчанию "x1" (то есть текущее количество доступных процессоров * 1)scala.concurrent.context.maxExtraThreads= по умолчанию "256"
Размер пула потоков затем numThreads ограничен minThreads снизу и maxThreads сверху.
maxExtraThreads — максимальное количество дополнительных потоков в любой момент времени для предотвращения тупика, см. scala.concurrent.blocking.
Контекст выполнения global может быть использован явно, определением implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global, или импортом ExecutionContext.Implicits.global.
Группировка кратковременных вложенных задач
Асинхронный код с кратковременными вложенными задачами выполняется эффективнее при использовании ExecutionContext.opportunistic (продолжайте чтение, чтобы узнать, почему это private[scala] и как к нему получить доступ).
ExecutionContext.opportunistic использует тот же пул потоков, что и ExecutionContext.global. Он пытается сгруппировать вложенные задачи и выполнить их в том же потоке, что и окружающая задача. Это идеально подходит для выполнения кратковременных задач, так как это уменьшает накладные расходы на переключение контекста.
ПРЕДУПРЕЖДЕНИЕ: длительные и/или блокирующие задачи должны быть обозначены в scala.concurrent.blocking-блоках, чтобы убедиться, что любые ожидающие задачи в текущей группе могут быть выполнены другим потоком в global.
Как использовать
Это поле private[scala] для сохранения бинарной совместимости. Оно было добавлено в 2.13.4, код, который ссылается на него напрямую, не работает с Scala библиотекой 2.13.0-3.
Библиотеки не должны ссылаться на это поле напрямую, потому что пользователи библиотеки могут использовать более раннюю версию Scala. Для использования группирующего ExecutionContext в библиотеке код должен использовать global в случае отсутствия поля opportunistic (пример ниже). Результирующий ExecutionContext имеет поведение группировки во всех версиях Scala 2.13 (global имеет группировку в 2.13.0-3).
implicit val ec: scala.concurrent.ExecutionContext = try {
scala.concurrent.ExecutionContext.getClass
.getDeclaredMethod("opportunistic")
.invoke(scala.concurrent.ExecutionContext)
.asInstanceOf[scala.concurrent.ExecutionContext]
} catch {
case _: NoSuchMethodException =>
scala.concurrent.ExecutionContext.global
}
Авторы приложений могут безопасно использовать это поле, потому что версия Scala во время выполнения такая же, как и во время компиляции. Варианты обхода ограничения доступа включают:
Использование структурного типа (пример ниже). Это использует рефлексию во время выполнения.
Написание Scala
objectв пакетеscala(пример ниже).Написание файла исходного кода Java. Это работает, потому что
private[scala]излучается какpublicв байткоде Java.
// Option 1
implicit val ec: scala.concurrent.ExecutionContext =
(scala.concurrent.ExecutionContext:
{def opportunistic: scala.concurrent.ExecutionContextExecutor}
).opportunistic
// Option 2
package scala {
object OpportunisticEC {
implicit val ec: scala.concurrent.ExecutionContext =
scala.concurrent.ExecutionContext.opportunistic
}
}
| Возвращает | глобальное ExecutionContext |
|---|
© 2002-2022 EPFL, with contributions from Lightbend.
Licensed under the Apache License, Version 2.0.
https://scala-lang.org/api/3.1.1/scala/concurrent/ExecutionContext$.html