Object ExecutionContext.ExecutionContext
object ExecutionContext
Содержит фабричные методы для создания контекстов выполнения.
| Супертипы | |
|---|---|
| Тип самого себя |
Классы
Исходный код
object Implicits
Исходный код
object parasitic extends ExecutionContextExecutor
ПРЕДУПРЕЖДЕНИЕ: Выполняйте только логику, которая быстро вернёт управление вызывающей стороне.
Этот ExecutionContext крадёт время выполнения у других потоков, заставляя свои Runnable работать в Thread, который вызывает execute и затем возвращает управление вызывающей стороне после выполнения *всех* своих Runnable. Вложенные вызовы execute будут обрабатываться с помощью трамплина, чтобы предотвратить неконтролируемый рост стека.
При использовании parasitic с абстракциями, такими как Future в многих случаях порядок выполнения логики Thread непредсказуем, так как зависит от того, когда/если завершится Future.
Не вызывайте блокирующие операции в Runnables, переданных в этот 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.2.0/scala/concurrent/ExecutionContext$.html