• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.coroutines
6 
7 import java.util.concurrent.*
8 import java.util.concurrent.atomic.AtomicInteger
9 
10 /**
11  * Creates a coroutine execution context using a single thread with built-in [yield] support.
12  * **NOTE: The resulting [ExecutorCoroutineDispatcher] owns native resources (its thread).
13  * Resources are reclaimed by [ExecutorCoroutineDispatcher.close].**
14  *
15  * If the resulting dispatcher is [closed][ExecutorCoroutineDispatcher.close] and
16  * attempt to submit a continuation task is made,
17  * then the [Job] of the affected task is [cancelled][Job.cancel] and the task is submitted to the
18  * [Dispatchers.IO], so that the affected coroutine can cleanup its resources and promptly complete.
19  *
20  * This is a **delicate** API. The result of this method is a closeable resource with the
21  * associated native resources (threads). It should not be allocated in place,
22  * should be closed at the end of its lifecycle, and has non-trivial memory and CPU footprint.
23  * If you do not need a separate thread-pool, but only have to limit effective parallelism of the dispatcher,
24  * it is recommended to use [CoroutineDispatcher.limitedParallelism] instead.
25  *
26  * If you need a completely separate thread-pool with scheduling policy that is based on the standard
27  * JDK executors, use the following expression:
28  * `Executors.newSingleThreadExecutor().asCoroutineDispatcher()`.
29  * See [Executor.asCoroutineDispatcher] for details.
30  *
31  * @param name the base name of the created thread.
32  */
33 @DelicateCoroutinesApi
34 public actual fun newSingleThreadContext(name: String): ExecutorCoroutineDispatcher =
35     newFixedThreadPoolContext(1, name)
36 
37 /**
38  * Creates a coroutine execution context with the fixed-size thread-pool and built-in [yield] support.
39  * **NOTE: The resulting [ExecutorCoroutineDispatcher] owns native resources (its threads).
40  * Resources are reclaimed by [ExecutorCoroutineDispatcher.close].**
41  *
42  * If the resulting dispatcher is [closed][ExecutorCoroutineDispatcher.close] and
43  * attempt to submit a continuation task is made,
44  * then the [Job] of the affected task is [cancelled][Job.cancel] and the task is submitted to the
45  * [Dispatchers.IO], so that the affected coroutine can cleanup its resources and promptly complete.
46  *
47  * This is a **delicate** API. The result of this method is a closeable resource with the
48  * associated native resources (threads). It should not be allocated in place,
49  * should be closed at the end of its lifecycle, and has non-trivial memory and CPU footprint.
50  * If you do not need a separate thread-pool, but only have to limit effective parallelism of the dispatcher,
51  * it is recommended to use [CoroutineDispatcher.limitedParallelism] instead.
52  *
53  * If you need a completely separate thread-pool with scheduling policy that is based on the standard
54  * JDK executors, use the following expression:
55  * `Executors.newFixedThreadPool().asCoroutineDispatcher()`.
56  * See [Executor.asCoroutineDispatcher] for details.
57  *
58  * @param nThreads the number of threads.
59  * @param name the base name of the created threads.
60  */
61 @DelicateCoroutinesApi
62 public actual fun newFixedThreadPoolContext(nThreads: Int, name: String): ExecutorCoroutineDispatcher {
63     require(nThreads >= 1) { "Expected at least one thread, but $nThreads specified" }
64     val threadNo = AtomicInteger()
65     val executor = Executors.newScheduledThreadPool(nThreads) { runnable ->
66         val t = Thread(runnable, if (nThreads == 1) name else name + "-" + threadNo.incrementAndGet())
67         t.isDaemon = true
68         t
69     }
70     return executor.asCoroutineDispatcher()
71 }
72