Come sincronizzare le coroutine su Android?
sobes.tech AI
Risposta dell'AI
Per sincronizzare le coroutine in Android, si possono usare diversi approcci a seconda del compito specifico:
-
Join: Attendere il completamento di un'altra coroutine.
// Avviare la prima coroutine val job1 = CoroutineScope(Dispatchers.Default).launch { delay(1000) println("Job 1 completato") } // Avviare la seconda coroutine val job2 = CoroutineScope(Dispatchers.Default).launch { delay(500) println("Job 2 completato") } // Attendere la fine di entrambe le coroutine job1.join() job2.join() println("Tutti i lavori completati") -
Await: Attendere il risultato di un'operazione asincrona rappresentata da Deferred.
// Operazione asincrona che restituisce un risultato val deferredResult = CoroutineScope(Dispatchers.Default).async { delay(1000) "Risultato da async" } // Attendere il risultato val result = deferredResult.await() println(result) -
CoroutineScope.coroutineScope: Creare un nuovo ambito di visibilità che termina solo dopo il completamento di tutte le coroutine figlie. Utile per la concorrenza strutturata.
suspend fun doParallelWork() { coroutineScope { // Creare un nuovo scope di concorrenza strutturata launch { delay(1000); println("Task 1 completato") } launch { delay(500); println("Task 2 completato") } } // Questo punto sarà raggiunto solo dopo il completamento di task 1 e task 2 println("Tutte le attività parallele completate") } -
Semantica degli attori (Channel): Per lo scambio di messaggi e la sincronizzazione dell'accesso a dati modificabili tra coroutine.
// Creare un canale per scambiare Int val channel = Channel<Int>() CoroutineScope(Dispatchers.Default).launch { // Inviare dati nel canale for (i in 1..5) { channel.send(i) } channel.close() // Chiudere il canale dopo l'invio } CoroutineScope(Dispatchers.Default).launch { // Ricevere dati dal canale for (value in channel) { println("Ricevuto $value") } } -
Mutex: Per garantire accesso esclusivo a una risorsa condivisa.
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock val mutex = Mutex() var counter = 0 suspend fun incrementCounter() { mutex.withLock { // Acquisire il mutex counter++ // Il mutex verrà automaticamente rilasciato all'uscita dal blocco } }
La scelta del metodo dipende da cosa si deve sincronizzare esattamente: attendere il completamento, ottenere un risultato, gestire attività parallele, scambiare dati o accesso esclusivo. coroutineScope è l'approccio raccomandato di default per la concorrenza strutturata.