Kotlin Academy · Pelajaran

Actor dan Pengurusan Keadaan Berstruktur

Gunakan corak bergaya actor untuk menyiri akses keadaan dalam kod serentak.

Pelajaran 4 daripada 413 langkah

Actor dan Pengurusan Keadaan Berstruktur ialah pelajaran Kotlin Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Kotlin Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Kotlin Academy merangkumi sejumlah 4 pelajaran.

Apakah Itu Aktor?

Aktor ialah korutin yang memiliki keadaan boleh ubah peribadi dan berkomunikasi melalui saluran. Kod luaran tidak pernah mengakses keadaan itu secara terus — sebaliknya, akses hanya dilakukan melalui mesej.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
sealed class CounterMsg
object Increment : CounterMsg()
class GetCount(val response: CompletableDeferred<Int>) : CounterMsg()
fun CoroutineScope.counterActor() = actor<CounterMsg> {
    var counter = 0
    for (msg in channel) {
        when (msg) {
            is Increment -> counter++
            is GetCount  -> msg.response.complete(counter)
        }
    }
}

Menggunakan Aktor

Hantar mesej kepada aktor menggunakan send. Aktor memproses mesej satu demi satu dan menyusun akses kepada keadaan secara bersiri.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
// (CounterMsg sealed class from previous scene)
fun main() = runBlocking {
    val counter = counterActor()
    repeat(100) { counter.send(Increment) }
    val response = CompletableDeferred<Int>()
    counter.send(GetCount(response))
    println("Count: ${response.await()}") // 100
    counter.close()
}

Aktor Menggantikan Kunci Pengecualian Bersama

Aktor menghapuskan keperluan terhadap kunci pengecualian bersama dengan menjadikan akses kepada keadaan berjujukan melalui reka bentuk. Semua perubahan berlaku dalam satu korutin.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
sealed class Msg
object Inc : Msg()
data class Get(val d: CompletableDeferred<Int>) : Msg()
fun CoroutineScope.safeCounter() = actor<Msg> {
    var n = 0
    for (m in channel) when(m) {
        is Inc -> n++
        is Get -> m.d.complete(n)
    }
}
fun main() = runBlocking {
    val a = safeCounter()
    repeat(1000) { a.send(Inc) }
    val d = CompletableDeferred<Int>()
    a.send(Get(d))
    println(d.await()) // 1000
    a.close()
}

Protokol Mesej Berjenis

Tentukan protokol mesej anda sebagai hierarki kelas termeterai untuk pengendalian semua kes dalam ungkapan pemilihan aktor.

sealed class BankMsg
data class Deposit(val amount: Double) : BankMsg()
data class Withdraw(val amount: Double, val result: CompletableDeferred<Boolean>) : BankMsg()
data class Balance(val result: CompletableDeferred<Double>) : BankMsg()
// Actor holds balance privately — outside code sends messages only

Mesin Keadaan sebagai Aktor

Aktor ialah mesin keadaan semula jadi: peralihan keadaan dalaman berlaku secara atomik sebagai tindak balas terhadap mesej.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
enum class TrafficState { RED, GREEN, YELLOW }
fun CoroutineScope.trafficLight() = actor<Unit> {
    var state = TrafficState.RED
    for (msg in channel) {
        state = when (state) {
            TrafficState.RED    -> TrafficState.GREEN
            TrafficState.GREEN  -> TrafficState.YELLOW
            TrafficState.YELLOW -> TrafficState.RED
        }
        println("State: $state")
    }
}
fun main() = runBlocking {
    val light = trafficLight()
    repeat(6) { light.send(Unit) }
    light.close()
}

Pembina aktor()

Pembina coroutine actor { } mencipta aktor dengan peti masuk saluran. Aktor ialah coroutine yang memproses mesej daripada channel.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun CoroutineScope.logActor() = actor<String>(capacity = Channel.BUFFERED) {
    val log = mutableListOf<String>()
    for (msg in channel) {
        log.add(msg)
        println("[LOG] $msg")
    }
    println("Log entries: ${log.size}")
}
fun main() = runBlocking {
    val logger = logActor()
    repeat(5) { logger.send("Event $it") }
    logger.close()
    // actor finishes after close
}

Menghentikan Aktor

Tutup saluran penghantaran aktor dengan close(). Gelung for dalam aktor akan berakhir, lalu membolehkan pembersihan dilakukan sebelum coroutine selesai.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
    val actor = actor<String> {
        for (msg in channel) println("Got: $msg")
        println("Actor done")
    }
    actor.send("hello")
    actor.send("world")
    actor.close()
    // Wait for actor to finish
    delay(50)
}

Aktor dengan Tekanan Balik

Tetapkan kapasiti saluran aktor untuk menggunakan tekanan balik — penghantar akan digantung apabila peti masuk penuh.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun CoroutineScope.slowProcessor() = actor<Int>(capacity = 2) {
    for (item in channel) {
        delay(100) // slow processing
        println("Processed: $item")
    }
}
fun main() = runBlocking {
    val proc = slowProcessor()
    repeat(5) { proc.send(it) } // sender suspends when capacity full
    proc.close()
}

Prestasi Aktor berbanding Mutex

Aktor mensiri akses tanpa perebutan kunci dan sesuai untuk keadaan kompleks dengan berbilang jenis mesej. Mutex lebih ringkas untuk satu pembilang dikongsi, tetapi kurang mudah digubah.

import kotlinx.coroutines.*
import kotlinx.coroutines.sync.*
// For a simple counter: Mutex is fine
val mutex = Mutex()
var simpleCounter = 0
// For complex state + multiple operations: Actor is cleaner
// Actor: messages describe intent; state changes are encapsulated
fun main() = runBlocking { println("Choose based on state complexity") }

CompletableDeferred untuk Permintaan-Balasan

Untuk corak permintaan-balasan dalam aktor, sertakan CompletableDeferred dalam mesej. Aktor melengkapkannya; penghantar menunggunya.

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
data class Query(val key: String, val reply: CompletableDeferred<String?>)
fun CoroutineScope.cacheActor() = actor<Any> {
    val cache = mutableMapOf<String, String>()
    for (msg in channel) when (msg) {
        is Pair<*, *> -> cache[msg.first as String] = msg.second as String
        is Query -> msg.reply.complete(cache[msg.key])
    }
}

Alternatif Moden: StateFlow + coroutineScope

Pembina actor bersifat eksperimen dan mungkin tidak digunakan lagi. Alternatif moden ialah kelas ViewModel atau perkhidmatan dengan MutableStateFlow yang dikemas kini daripada satu coroutine.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
class CounterService(scope: CoroutineScope) {
    private val _count = MutableStateFlow(0)
    val count = _count.asStateFlow()
    private val events = kotlinx.coroutines.channels.Channel<Unit>()
    init {
        scope.launch {
            for (e in events) _count.value++
        }
    }
    fun increment() { events.trySend(Unit) }
}

Semakan Pantas

Bagaimanakah aktor memastikan akses serentak yang selamat kepada keadaan?

Imbas Kembali

Aktor merangkum keadaan boleh ubah dalam satu coroutine dan mendedahkan operasi sebagai mesej saluran yang ditaip. Aktor secara semula jadi mensiri akses, menyokong mesin keadaan dan menghapuskan perebutan kunci — dengan kos indirection penghantaran mesej.

Percuma untuk bermula

Pelajari Kotlin dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
51
Pelajaran
203

Soalan Lazim

Adakah pelajaran “Actor dan Pengurusan Keadaan Berstruktur” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Kotlin Academy, termasuk “Actor dan Pengurusan Keadaan Berstruktur”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Kotlin Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Actor dan Pengurusan Keadaan Berstruktur”?

Gunakan corak bergaya actor untuk menyiri akses keadaan dalam kod serentak. Anda berlatih Kotlin Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Kotlin Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Kotlin Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Actor dan Pengurusan Keadaan Berstruktur” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Kotlin Academy ini?

Ya. Setiap pelajaran Kotlin Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Asas Channel: send, receive dan close
  2. Jenis Channel: Rendezvous, Buffered, Conflated, Unlimited
  3. Mutex dan Semaphore untuk Keadaan Dikongsi
  4. Actor dan Pengurusan Keadaan Berstruktur
← Kembali ke Kotlin Academy