Java/Kotlin
[Coroutine] 코루틴 학습 - 13 (Actors)
Icarus8050
2022. 5. 17. 14:22
반응형
Actor
- 컴퓨터 과학에서 Actor model은 Actor를 병렬 컴퓨팅의 보편적인 기본 요소로 취급하는 수학적 모델이다.
- 액터는 메시지에 대한 응답으로 지역적인 결정을 내리고, 더 많은 액터를 생성하고, 메시지를 전송하고, 수신된 다음 메시지에 응답하는 방법을 결정할 수 있다.
- 액터는 자신의 비공개 상태를 수정할 수 있지만 메시징을 통해 간접적으로만 서로에게 영향을 줄 수 있다. (이는 잠금 기반의 동기화 필요성을 없앤다.)
- 각각의 액터는 싱글 쓰레드로 동작하고 메시지를 차례로 처리한다.
코루틴에서는 액터를 꽤나 쉽게 구현할 수 있다.
아래의 예시는 동기화 문제가 발생하지 않는다. 액터가 싱글쓰레드로 동작하고 있기 때문이다. 액터 모델을 간단하게 만들기 위해서는 코루틴 빌더를 이용하면 된다.
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 CoroutineScope.massiveRun(action: suspend () -> Unit) {
val n = 100
val k = 1000
val time = measureTimeMillis {
val jobs = List(n) {
launch {
repeat(k) {
action()
}
}
}
jobs.forEach { it.join() }
}
println("Completed ${n * k} actions in $time ms")
}
suspend fun main(): Unit = coroutineScope {
val counter: SendChannel<CounterMsg> = counterActor()
massiveRun { counter.send(IncCounter) }
val response = CompletableDeferred<Int>()
counter.send(GetCounter(response))
println(response.await())
counter.close()
}
참고자료
https://www.amazon.com/Kotlin-Coroutines-Deep-Marcin-Moskala/dp/8396395837
https://kotlinlang.org/docs/shared-mutable-state-and-concurrency.html#actors
반응형