각각의 액터들은 서로 메세지를 통해서 통신을 하고, 각각의 액터들은 single thread 로 작동한다. 이러한 액터를 우리는 channel을 통해 구현할 수 있다.
sealed class CounterMsg
object IncCounter : CounterMsg()
class GetCounter (
val response : CompletableDeferred<Int>
) : CounterMsg()
fun CoroutineScope.counterActor() : Channel<CounterMsg> {
val channel = Channel<CounterMsg>()
launch {
var counter = 0
for (msg in channel) {
when(msg) {
is IncCounter -> counter++
is GetCounter -> msg.response.complete(counter)
}
}
}
return channel
}
suspend fun main() : Unit = coroutineScope {
val counter : SendChannel<CounterMsg> = counterActor()
counter.send(IncCounter)
val response = CompletableDeferred<Int>()
counter.send(GetCounter(response))
counter.close()
}
앞서 말했듯이 actor 객체는 single-thread로 실행되는 것을 기본 전제로 하기 때문에, 동시성 문제로 동기화를 할 필요가 없다.