Middle
Quali elementi di multithreading fornisce Kotlin?
sobes.tech AI
Risposta dell'AI
Kotlin fornisce i seguenti elementi di concorrenza:
- Coroutines: Thread leggeri basati su funzioni sospese. Consentono l'esecuzione asincrona e non bloccante del codice.
- Costruttori di coroutine: Funzioni che avviano coroutine. Principali:
launch(avvia una coroutine senza restituire un valore),async(avvia una coroutine e restituisce unDeferred, che può essere atteso per ottenere il risultato).// Esempio di utilizzo di launch GlobalScope.launch { println("Ciao dalla coroutine ${Thread.currentThread().name}") } // Esempio di utilizzo di async val deferred = GlobalScope.async { delay(1000) // Simula un'operazione lunga "Risultato" } val result = runBlocking { deferred.await() } // Attende il risultato Dispatchers: Determinano su quale pool di thread verrà eseguita la coroutine. Principali:Dispatchers.Default: Pool generale per compiti intensivi in CPU.Dispatchers.IO: Pool per operazioni di input/output bloccanti (file, rete).Dispatchers.Main: Dispatcher per il thread dell'interfaccia utente sulle piattaforme appropriate (Android, Swing).Dispatchers.Unconfined: La coroutine viene avviata nel thread corrente, ma può essere ripresa in qualsiasi thread.
GlobalScope.launch(Dispatchers.IO) { // Esecuzione di input/output }runBlocking: Funzione costruttore di coroutine che blocca il thread corrente fino al completamento della coroutine. Viene usata per combinare codice bloccante e non bloccante, spesso nei test o nelle funzioni main.runBlocking { launch { delay(500) println("Completato in ${Thread.currentThread().name}") } println("Avviato in ${Thread.currentThread().name}") }- Funzioni
suspend: Funzioni il cui esecuzione può essere sospesa e ripresa. Possono essere chiamate solo da altre funzionisuspendo costruttori di coroutine.suspend fun doSomething() { delay(100) // Esempio di sospensione } Job: Handle per una coroutine in esecuzione. Fornisce metodi per gestire il ciclo di vita della coroutine (annullare, attendere il completamento).val job = GlobalScope.launch { // Operazione lunga } job.cancel() // Annulla la coroutine runBlocking { job.join() } // Attende il completamentoCoroutineScope: Definisce un ambito per le coroutine. Le coroutine lanciate in un ambito specifico vengono automaticamente annullate alla cancellazione dell'ambito. Aiuta a gestire il ciclo di vita delle coroutine.val scope = CoroutineScope(Dispatchers.Default) scope.launch { // Coroutine in questo ambito } scope.cancel() // Annulla tutte le coroutine in questo ambito- Canali (
Channel): Primitive per il trasferimento sicuro di dati tra coroutine. I canali possono essere unidirezionali (solo invio o ricezione) o bidirezionali.import kotlinx.coroutines.channels.Channel val channel = Channel<Int>() runBlocking { launch { for (x in 1..5) channel.send(x * x) channel.close() // È importante chiudere il canale } launch { for (y in channel) println(y) } } - Mutex (
Mutex): Primitive di sincronizzazione per garantire accesso esclusivo a una risorsa condivisa. Garantisce la sicurezza dei thread, permettendo a una sola coroutine di possedere il mutex in un dato momento.import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock val mutex = Mutex() var counter = 0 suspend fun incrementCounter() { mutex.withLock { counter++ } } - Stati (
StateFlow,SharedFlow): Primitive per lavorare con flussi di dati nel contesto della programmazione reattiva e concorrente.StateFlowrappresenta un flusso "freddo" con lo stato attuale, mentreSharedFlowè un flusso "caldo" per la diffusione di dati.