Skip to content

Commit

Permalink
Update scaladocs
Browse files Browse the repository at this point in the history
  • Loading branch information
lrytz committed Nov 9, 2020
1 parent 94390f0 commit 48c5232
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 29 deletions.
8 changes: 4 additions & 4 deletions src/library/scala/concurrent/BlockContext.scala
Expand Up @@ -13,12 +13,12 @@
package scala.concurrent

/**
* A context to be notified by `scala.concurrent.blocking` when
* A context to be notified by [[scala.concurrent.blocking]] when
* a thread is about to block. In effect this trait provides
* the implementation for `scala.concurrent.Await`.
* `scala.concurrent.Await.result()` and `scala.concurrent.Await.ready()`
* the implementation for [[scala.concurrent.Await]].
* [[scala.concurrent.Await.result]] and [[scala.concurrent.Await.ready]]
* locates an instance of `BlockContext` by first looking for one
* provided through `BlockContext.withBlockContext()` and failing that,
* provided through [[BlockContext.withBlockContext]] and failing that,
* checking whether `Thread.currentThread` is an instance of `BlockContext`.
* So a thread pool can have its `java.lang.Thread` instances implement
* `BlockContext`. There's a default `BlockContext` used if the thread
Expand Down
81 changes: 56 additions & 25 deletions src/library/scala/concurrent/ExecutionContext.scala
Expand Up @@ -32,8 +32,8 @@ import scala.annotation.implicitNotFound
* While it is possible to simply import
* `scala.concurrent.ExecutionContext.Implicits.global` to obtain an
* implicit `ExecutionContext`, application developers should carefully
* consider where they want to set execution policy;
* ideally, one place per applicationor per logically related section of code—
* consider where they want to define the execution policy;
* ideally, one place per applicationor per logically related section of code
* will make a decision about which `ExecutionContext` to use.
* That is, you will mostly want to avoid hardcoding, especially via an import,
* `scala.concurrent.ExecutionContext.Implicits.global`.
Expand All @@ -57,12 +57,12 @@ import scala.annotation.implicitNotFound
* knowing that only that library's network operations will be affected.
* Application callback execution can be configured separately.
*/
@implicitNotFound("""Cannot find an implicit ExecutionContext. You might pass
@implicitNotFound("""Cannot find an implicit ExecutionContext. You might add
an (implicit ec: ExecutionContext) parameter to your method.
The ExecutionContext is used to configure how and on which
thread pools Futures will run, so the specific ExecutionContext
that is selected is important.
thread pools asynchronous tasks (such as Futures) will run,
so the specific ExecutionContext that is selected is important.
If your application does not define an ExecutionContext elsewhere,
consider using Scala's global ExecutionContext by defining
Expand Down Expand Up @@ -121,23 +121,27 @@ trait ExecutionContextExecutorService extends ExecutionContextExecutor with Exec
*/
object ExecutionContext {
/**
* The explicit global `ExecutionContext`. Invoke `global` when you want to provide the global
* `ExecutionContext` explicitly.
* The global [[ExecutionContext]] This default `ExecutionContext` implementation is backed by a work-stealing thread
* pool. It can be configured via the following system properties:
*
* The default `ExecutionContext` implementation is backed by a work-stealing thread pool.
* It can be configured via the following [[scala.sys.SystemProperties]]:
*
* `scala.concurrent.context.minThreads` = defaults to "1"
* `scala.concurrent.context.numThreads` = defaults to "x1" (i.e. the current number of available processors * 1)
* `scala.concurrent.context.maxThreads` = defaults to "x1" (i.e. the current number of available processors * 1)
* `scala.concurrent.context.maxExtraThreads` = defaults to "256"
* - `scala.concurrent.context.minThreads` = defaults to "1"
* - `scala.concurrent.context.numThreads` = defaults to "x1" (i.e. the current number of available processors * 1)
* - `scala.concurrent.context.maxThreads` = defaults to "x1" (i.e. the current number of available processors * 1)
* - `scala.concurrent.context.maxExtraThreads` = defaults to "256"
*
* The pool size of threads is then `numThreads` bounded by `minThreads` on the lower end and `maxThreads` on the high end.
*
* The `maxExtraThreads` is the maximum number of extra threads to have at any given time to evade deadlock,
* see [[scala.concurrent.BlockContext]].
* see [[scala.concurrent.blocking]].
*
* The `global` execution context can be used explicitly, by defining an
* `implicit val ec = ExecutionContext = ExecutionContext.global`, or by importing
* [[ExecutionContext.Implicits.global]].
*
* @note Asynchronous code with short-lived nested tasks is executed more efficiently when using
* [[ExecutionContext.opportunistic]].
*
* @return the global `ExecutionContext`
* @return the global [[ExecutionContext]]
*/
final lazy val global: ExecutionContextExecutor = impl.ExecutionContextImpl.fromExecutor(null: Executor)

Expand Down Expand Up @@ -167,11 +171,42 @@ object ExecutionContext {
}

/**
* This `ExecutionContext` is ideally suited to execute short-lived tasks on the `global` `ExecutionContext` as it
* attempts to locally batch the execution of nested tasks.
* This `ExecutionContext` uses the same thread pool as [[ExecutionContext.global]]. It attempts to batch nested
* task and execute them on the same thread as the enclosing task. This is ideally suited to execute short-lived tasks
* as it reduces the overhead of context switching.
*
* WARNING: long-running and/or blocking tasks should be demarcated within `scala.concurrent.blocking`-blocks,
* WARNING: long-running and/or blocking tasks should be demarcated within [[scala.concurrent.blocking]]-blocks
* to ensure that any pending tasks in the current batch can be executed by another thread on `global`.
*
* === How to use ===
*
* This `ExecutionContext` is `private[scala]` to maintain binary compatibility. It was added in 2.13.3, code that
* uses it will fail to run with a 2.13.0-2 Scala library.
*
* Libraries should not reference this field because users of the library might be using an earlier Scala version.
*
* Application authors can safely use the field because the Scala version at run time is the same as at compile time.
* Options to bypass the access restriction include:
*
* 1. Using a structural type (see below). This uses reflection at run time.
* 1. Writing a Scala `object` in the `scala` package (see below).
* 1. Writing a Java source file. This works because `private[scala]` is emitted as `public` in Java bytecode.
*
* {{{
* // Option 1
* implicit lazy val ec: ExecutionContext =
* (scala.concurrent.ExecutionContext:
* {def opportunistic: scala.concurrent.ExecutionContextExecutor}
* ).opportunistic
*
* // Option 2
* package scala {
* object OpportunisticEC {
* implicit lazy val ec: scala.concurrent.ExecutionContext =
* scala.concurrent.ExecutionContext.opportunistic
* }
* }
* }}}
*/
private[scala] lazy val opportunistic: ExecutionContextExecutor = new ExecutionContextExecutor with BatchingExecutor {
final override def submitForExecution(runnable: Runnable): Unit = global.execute(runnable)
Expand All @@ -187,12 +222,8 @@ object ExecutionContext {

object Implicits {
/**
* The implicit global `ExecutionContext`. Import `global` when you want to provide the global
* `ExecutionContext` implicitly.
*
* The default `ExecutionContext` implementation is backed by a work-stealing thread pool. By default,
* the thread pool uses a target number of worker threads equal to the number of
* [[https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors-- available processors]].
* An accessor that can be used to import the global `ExecutionContext` into the implicit scope,
* see [[ExecutionContext.global]].
*/
implicit final def global: ExecutionContext = ExecutionContext.global
}
Expand Down

0 comments on commit 48c5232

Please sign in to comment.