Spec-Zone.ru › Scala 3.2

Object ExecutionContext.ExecutionContext

Класс-компаньон • Исходный код

object ExecutionContext

Содержит фабричные методы для создания контекстов выполнения.

Супертипы
класс Object
трайт Matchable
класс Any
Тип самого себя
ExecutionContext.type

Классы

Исходный код
object Implicits

Исходный код
object parasitic extends ExecutionContextExecutor

ПРЕДУПРЕЖДЕНИЕ: Выполняйте только логику, которая быстро вернёт управление вызывающей стороне.

Этот ExecutionContext крадёт время выполнения у других потоков, заставляя свои Runnable работать в Thread, который вызывает execute и затем возвращает управление вызывающей стороне после выполнения *всех* своих Runnable. Вложенные вызовы execute будут обрабатываться с помощью трамплина, чтобы предотвратить неконтролируемый рост стека.

При использовании parasitic с абстракциями, такими как Future в многих случаях порядок выполнения логики Thread непредсказуем, так как зависит от того, когда/если завершится Future.

Не вызывайте блокирующие операции в Runnables, переданных в этот ExecutionContext, так как это помешает прогрессу других ожидающих Runnable и вызывающей Thread.

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

Любые NonFatal или InterruptedException будут сообщены defaultReporter.

Конкретные методы

Исходный код
def fromExecutor(e: Executor, reporter: Throwable => Unit): ExecutionContextExecutor

Создаёт ExecutionContext из данного Executor.

Параметры значения
e

используемый Executor . Если null, создаётся новый Executor с стандартной конфигурацией.

reporter

функция для отчётности об ошибках

Возвращаемое значение

ExecutionContext , использующий данный Executor

Исходный код
def fromExecutor(e: Executor): ExecutionContextExecutor

Создаёт ExecutionContext из данного Executor со стандартным репортером.

Параметры значения
e

используемый Executor . Если null, создаётся новый Executor с стандартной конфигурацией.

Возвращаемое значение

ExecutionContext , использующий данный Executor

Исходный код
def fromExecutorService(e: ExecutorService, reporter: Throwable => Unit): ExecutionContextExecutorService

Создаёт ExecutionContext из данного ExecutorService.

Параметры значения
e

используемый ExecutorService. Если null, создаётся новый ExecutorService с настройками по умолчанию.

reporter

функция для отчётности об ошибках

Возвращает

ExecutionContext с использованием заданного ExecutorService

Исходный код
def fromExecutorService(e: ExecutorService): ExecutionContextExecutorService

Создаёт ExecutionContext из заданного ExecutorService с отчётностью по умолчанию.

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

import java.util.concurrent.Executors
val ec = ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor())
Параметры значения
e

используемый ExecutorService. Если null, создаётся новый ExecutorService с настройками по умолчанию.

Возвращает

ExecutionContext с использованием заданного ExecutorService

Конкретные поля

Исходный код
final val defaultReporter: Throwable => Unit

Отчётность по умолчанию просто выводит трассировку стека 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 во время выполнения такая же, как и во время компиляции. Варианты обхода ограничения доступа включают:

  1. Использование структурного типа (пример ниже). Это использует рефлексию во время выполнения.

  2. Написание Scala object в пакете scala (пример ниже).

  3. Написание файла исходного кода 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

Spec-Zone.ru

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