Sobes.tech
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 a Deferred that 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}")
    }
    
  • suspend functions: Functions that can be suspended and resumed. They can only be called from other suspend functions 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 completion
    
  • CoroutineScope: 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. StateFlow is a "cold" stream with a current state, while SharedFlow is a "hot" stream for broadcasting data.
What multithreading elements does Kotlin provide… - sobes.tech