Middle
What multithreading elements does Kotlin provide?
sobes.tech AI
Answer from AI
Kotlin provides the following concurrency elements:
- Coroutines: Lightweight threads based on suspending functions. They enable asynchronous and non-blocking code execution.
- Coroutine builders: Functions that launch coroutines. Main ones include:
launch(starts a coroutine without returning a value),async(starts a coroutine and returns aDeferredthat can be awaited for a result).// Example of using launch GlobalScope.launch { println("Hello from coroutine ${Thread.currentThread().name}") } // Example of using async val deferred = GlobalScope.async { delay(1000) // Simulate a long operation "Result" } val result = runBlocking { deferred.await() } // Await the result Dispatchers: Define on which thread pool the coroutine will run. Main ones include:Dispatchers.Default: Common thread pool for CPU-intensive tasks.Dispatchers.IO: Thread pool for blocking IO operations (file, network).Dispatchers.Main: Dispatcher for the UI thread on platforms like Android, Swing.Dispatchers.Unconfined: Coroutine starts in the current thread but can resume in any thread.
GlobalScope.launch(Dispatchers.IO) { // Perform IO }runBlocking: A coroutine builder function that blocks the current thread until the coroutine completes. Used to bridge blocking and non-blocking code, often in tests or main functions.runBlocking { launch { delay(500) println("Completed in ${Thread.currentThread().name}") } println("Launched in ${Thread.currentThread().name}") }suspendfunctions: Functions that can be suspended and resumed. They can only be called from othersuspendfunctions or coroutine builders.suspend fun doSomething() { delay(100) // Example of suspension }Job: Handle to a launched coroutine. Provides methods to manage the coroutine's lifecycle (cancel, wait for completion).val job = GlobalScope.launch { // Long operation } job.cancel() // Cancel the coroutine runBlocking { job.join() } // Wait for completionCoroutineScope: Defines the scope for coroutines. Coroutines launched within a scope are automatically canceled when the scope is canceled. Helps manage coroutine lifecycle.val scope = CoroutineScope(Dispatchers.Default) scope.launch { // Coroutine within this scope } scope.cancel() // Cancel all coroutines in this scope- Channels (
Channel): Primitives for safe data transfer between coroutines. Channels can be unidirectional (send or receive only) or bidirectional.import kotlinx.coroutines.channels.Channel val channel = Channel<Int>() runBlocking { launch { for (x in 1..5) channel.send(x * x) channel.close() // Important to close the channel } launch { for (y in channel) println(y) } } - Mutexes (
Mutex): Synchronization primitives to ensure exclusive access to shared resources. They provide thread safety, allowing only one coroutine to own the mutex at a time.import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock val mutex = Mutex() var counter = 0 suspend fun incrementCounter() { mutex.withLock { counter++ } } - States (
StateFlow,SharedFlow): Primitives for working with data streams in reactive programming and concurrency.StateFlowis a "cold" stream with a current state, whileSharedFlowis a "hot" stream for broadcasting data.