Actor dan Pengelolaan Status Terstruktur
Gunakan pola bergaya actor untuk menserialkan akses status dalam kode konkuren.
Actor dan Pengelolaan Status Terstruktur adalah pelajaran Kotlin Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Kotlin Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Kotlin Academy mencakup 4 pelajaran total.
Apa Itu Aktor?
aktor adalah coroutine yang memiliki status berubah-ubah pribadi dan berkomunikasi melalui kanal. Kode eksternal tidak pernah mengakses status tersebut secara langsung — akses hanya dilakukan melalui pesan.
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
Kirim pesan ke aktor menggunakan send. Aktor memprosesnya satu per satu sehingga akses status menjadi berurutan.
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 Saling Kunci
Aktor menghilangkan kebutuhan akan saling kunci dengan membuat akses status berlangsung berurutan berdasarkan desain. Semua perubahan terjadi di dalam satu coroutine.
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 Pesan Bertipe
Definisikan protokol pesan Anda sebagai hierarki kelas tertutup agar dapat ditangani secara menyeluruh dalam ekspresi kondisional 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 onlyMesin Status sebagai Aktor
Aktor secara alami berperan sebagai mesin status: transisi status internal terjadi secara atomik sebagai respons terhadap pesan.
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()
}Pembuat actor()
Pembuat coroutine actor { } membuat aktor dengan kotak masuk channel. Aktor adalah coroutine yang memproses pesan dari 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 channel pengiriman aktor dengan close(). Perulangan for di dalam aktor berakhir, sehingga pembersihan dapat 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
Atur kapasitas channel aktor untuk menerapkan tekanan balik—pengirim ditangguhkan saat kotak 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()
}Performa Aktor vs Mutex
Aktor menserialisasikan akses tanpa persaingan kunci dan cocok untuk state kompleks dengan beberapa jenis pesan. Mutex lebih sederhana untuk satu penghitung bersama, tetapi kurang mudah dikomposisikan.
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 Pola Permintaan-Balasan
Untuk pola permintaan-balasan di dalam aktor, sertakan CompletableDeferred dalam pesan. Aktor menyelesaikannya; pengirim 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 Modern: StateFlow + coroutineScope
Pembuat actor bersifat eksperimental dan mungkin tidak digunakan lagi. Alternatif modernnya adalah kelas ViewModel atau layanan dengan MutableStateFlow yang diperbarui dari 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) }
}Pemeriksaan Singkat
Bagaimana aktor memastikan akses state secara konkuren tetap aman?
Ringkasan
Aktor mengenkapsulasi state yang dapat diubah dalam satu coroutine dan mengekspos operasi sebagai pesan channel bertipe. Aktor secara alami menserialisasikan akses, mendukung mesin state, dan menghilangkan persaingan kunci—dengan konsekuensi adanya indireksi pengiriman pesan.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Actor dan Pengelolaan Status Terstruktur” gratis?
Ya — teks lengkap “Actor dan Pengelolaan Status Terstruktur” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Kotlin Academy, upgrade ke CoddyKit PRO. Kursus Kotlin Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Actor dan Pengelolaan Status Terstruktur”?
Gunakan pola bergaya actor untuk menserialkan akses status dalam kode konkuren. Kamu berlatih Kotlin Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Kotlin Academy?
Tidak diperlukan pengalaman sebelumnya. Kotlin Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “Actor dan Pengelolaan Status Terstruktur” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Kotlin Academy ini?
Ya. Setiap pelajaran Kotlin Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Dasar Channel: send, receive, dan close
- Tipe Channel: Rendezvous, Buffered, Conflated, Unlimited
- Mutex dan Semaphore untuk Status Bersama
- Actor dan Pengelolaan Status Terstruktur