Sobes.tech
Middle+

Πώς να συγχρονίσετε τις κορουτίνες στο Android;

sobes.tech AI

Απάντηση από AI

Για τον συγχρονισμό των coroutine στο Android, μπορούν να χρησιμοποιηθούν διάφορες προσεγγίσεις, ανάλογα με την συγκεκριμένη εργασία:

  • Join: Αναμονή για την ολοκλήρωση μιας άλλης coroutine.

    // Ξεκινάμε την πρώτη coroutine
    val job1 = CoroutineScope(Dispatchers.Default).launch {
        delay(1000)
        println("Job 1 ολοκληρώθηκε")
    }
    
    // Ξεκινάμε τη δεύτερη coroutine
    val job2 = CoroutineScope(Dispatchers.Default).launch {
        delay(500)
        println("Job 2 ολοκληρώθηκε")
    }
    
    // Περιμένουμε να ολοκληρωθούν και οι δύο
    job1.join()
    job2.join()
    
    println("Όλες οι εργασίες ολοκληρώθηκαν")
    
  • Await: Αναμονή για το αποτέλεσμα μιας ασύγχρονης λειτουργίας που εκπροσωπείται από το Deferred.

    // Ασύγχρονη λειτουργία που επιστρέφει αποτέλεσμα
    val deferredResult = CoroutineScope(Dispatchers.Default).async {
        delay(1000)
        "Αποτέλεσμα από το async"
    }
    
    // Αναμονή για το αποτέλεσμα
    val result = deferredResult.await()
    println(result)
    
  • CoroutineScope.coroutineScope: Δημιουργία μιας νέας περιοχής που θα τερματίσει μόνο μετά την ολοκλήρωση όλων των παιδικών coroutine. Χρήσιμο για δομημένο ανταγωνισμό.

    suspend fun doParallelWork() {
        coroutineScope { // Δημιουργία νέου scope δομημένου ανταγωνισμού
            launch { delay(1000); println("Εργασία 1 ολοκληρώθηκε") }
            launch { delay(500); println("Εργασία 2 ολοκληρώθηκε") }
        } // Αυτό το σημείο θα επιτευχθεί μόνο μετά την ολοκλήρωση των εργασιών 1 και 2
        println("Όλες οι παράλληλες εργασίες ολοκληρώθηκαν")
    }
    
  • Σημασιολογία των ηθοποιών (Channel): Για ανταλλαγή μηνυμάτων και συγχρονισμό πρόσβασης σε μεταβαλλόμενα δεδομένα μεταξύ coroutine.

    // Δημιουργία καναλιού για ανταλλαγή Int
    val channel = Channel<Int>()
    
    CoroutineScope(Dispatchers.Default).launch {
        // Αποστολή δεδομένων στο κανάλι
        for (i in 1..5) {
            channel.send(i)
        }
        channel.close() // Κλείσιμο καναλιού μετά την αποστολή
    }
    
    CoroutineScope(Dispatchers.Default).launch {
        // Λήψη δεδομένων από το κανάλι
        for (value in channel) {
            println("Λήφθηκε $value")
        }
    }
    
  • Mutex: Για διασφάλιση αποκλειστικής πρόσβασης σε κοινό πόρο.

    import kotlinx.coroutines.sync.Mutex
    import kotlinx.coroutines.sync.withLock
    
    val mutex = Mutex()
    var counter = 0
    
    suspend fun incrementCounter() {
        mutex.withLock { // Απόκτηση mutex
            counter++
            // Το mutex θα απελευθερωθεί αυτόματα κατά την έξοδο από το μπλοκ
        }
    }
    

Η επιλογή της μεθόδου εξαρτάται από το τι ακριβώς χρειάζεται να συγχρονιστεί: αναμονή για ολοκλήρωση, λήψη αποτελέσματος, διαχείριση παράλληλων εργασιών, ανταλλαγή δεδομένων ή αποκλειστική πρόσβαση. Το coroutineScope είναι η προτεινόμενη προσέγγιση από προεπιλογή για δομημένο ανταγωνισμό.