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