1 /* 2 * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 @file:Suppress("unused") 6 7 package kotlinx.coroutines 8 9 import kotlinx.coroutines.internal.* 10 import kotlinx.coroutines.scheduling.* 11 import java.util.* 12 import kotlin.coroutines.* 13 14 /** 15 * Name of the property that defines the maximal number of threads that are used by [Dispatchers.IO] coroutines dispatcher. 16 */ 17 public const val IO_PARALLELISM_PROPERTY_NAME: String = "kotlinx.coroutines.io.parallelism" 18 19 /** 20 * Groups various implementations of [CoroutineDispatcher]. 21 */ 22 public actual object Dispatchers { 23 /** 24 * The default [CoroutineDispatcher] that is used by all standard builders like 25 * [launch][CoroutineScope.launch], [async][CoroutineScope.async], etc 26 * if no dispatcher nor any other [ContinuationInterceptor] is specified in their context. 27 * 28 * It is backed by a shared pool of threads on JVM. By default, the maximal level of parallelism used 29 * by this dispatcher is equal to the number of CPU cores, but is at least two. 30 * Level of parallelism X guarantees that no more than X tasks can be executed in this dispatcher in parallel. 31 */ 32 @JvmStatic 33 public actual val Default: CoroutineDispatcher = createDefaultDispatcher() 34 35 /** 36 * A coroutine dispatcher that is confined to the Main thread operating with UI objects. 37 * This dispatcher can be used either directly or via [MainScope] factory. 38 * Usually such dispatcher is single-threaded. 39 * 40 * Access to this property may throw [IllegalStateException] if no main thread dispatchers are present in the classpath. 41 * 42 * Depending on platform and classpath it can be mapped to different dispatchers: 43 * - On JS and Native it is equivalent of [Default] dispatcher. 44 * - On JVM it is either Android main thread dispatcher, JavaFx or Swing EDT dispatcher. It is chosen by 45 * [`ServiceLoader`](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html). 46 * 47 * In order to work with `Main` dispatcher, the following artifacts should be added to project runtime dependencies: 48 * - `kotlinx-coroutines-android` for Android Main thread dispatcher 49 * - `kotlinx-coroutines-javafx` for JavaFx Application thread dispatcher 50 * - `kotlinx-coroutines-swing` for Swing EDT dispatcher 51 * 52 * In order to set a custom `Main` dispatcher for testing purposes, add the `kotlinx-coroutines-test` artifact to 53 * project test dependencies. 54 * 55 * Implementation note: [MainCoroutineDispatcher.immediate] is not supported on Native and JS platforms. 56 */ 57 @JvmStatic 58 public actual val Main: MainCoroutineDispatcher get() = MainDispatcherLoader.dispatcher 59 60 /** 61 * A coroutine dispatcher that is not confined to any specific thread. 62 * It executes initial continuation of the coroutine in the current call-frame 63 * and lets the coroutine resume in whatever thread that is used by the corresponding suspending function, without 64 * mandating any specific threading policy. Nested coroutines launched in this dispatcher form an event-loop to avoid 65 * stack overflows. 66 * 67 * ### Event loop 68 * Event loop semantics is a purely internal concept and have no guarantees on the order of execution 69 * except that all queued coroutines will be executed on the current thread in the lexical scope of the outermost 70 * unconfined coroutine. 71 * 72 * For example, the following code: 73 * ``` 74 * withContext(Dispatchers.Unconfined) { 75 * println(1) 76 * withContext(Dispatchers.Unconfined) { // Nested unconfined 77 * println(2) 78 * } 79 * println(3) 80 * } 81 * println("Done") 82 * ``` 83 * Can print both "1 2 3" and "1 3 2", this is an implementation detail that can be changed. 84 * But it is guaranteed that "Done" will be printed only when both `withContext` are completed. 85 * 86 * 87 * Note that if you need your coroutine to be confined to a particular thread or a thread-pool after resumption, 88 * but still want to execute it in the current call-frame until its first suspension, then you can use 89 * an optional [CoroutineStart] parameter in coroutine builders like 90 * [launch][CoroutineScope.launch] and [async][CoroutineScope.async] setting it to the 91 * the value of [CoroutineStart.UNDISPATCHED]. 92 */ 93 @JvmStatic 94 public actual val Unconfined: CoroutineDispatcher = kotlinx.coroutines.Unconfined 95 96 /** 97 * The [CoroutineDispatcher] that is designed for offloading blocking IO tasks to a shared pool of threads. 98 * 99 * Additional threads in this pool are created and are shutdown on demand. 100 * The number of threads used by tasks in this dispatcher is limited by the value of 101 * "`kotlinx.coroutines.io.parallelism`" ([IO_PARALLELISM_PROPERTY_NAME]) system property. 102 * It defaults to the limit of 64 threads or the number of cores (whichever is larger). 103 * 104 * Moreover, the maximum configurable number of threads is capped by the 105 * `kotlinx.coroutines.scheduler.max.pool.size` system property. 106 * If you need a higher number of parallel threads, 107 * you should use a custom dispatcher backed by your own thread pool. 108 * 109 * ### Implementation note 110 * 111 * This dispatcher shares threads with a [Default][Dispatchers.Default] dispatcher, so using 112 * `withContext(Dispatchers.IO) { ... }` does not lead to an actual switching to another thread — 113 * typically execution continues in the same thread. 114 * As a result of thread sharing, more than 64 (default parallelism) threads can be created (but not used) 115 * during operations over IO dispatcher. 116 */ 117 @JvmStatic 118 public val IO: CoroutineDispatcher = DefaultScheduler.IO 119 } 120