Last active
May 1, 2024 14:46
-
-
Save posth2071/cbc3ad2cfc77906b2178c978dcf5ae88 to your computer and use it in GitHub Desktop.
코루틴빌더(CoroutineBuilder) Actor 사용 예시
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlinx.coroutines.* | |
import kotlinx.coroutines.channels.actor | |
import kotlin.system.measureTimeMillis | |
/* | |
* Sealed Class CounterMsg 정의 | |
* : Sealed class는 enum class의 확장판 개념 (enum은 상수들의 집합이라면 sealed는 클래스들의 집합) | |
* : Sealed Class는 모두 abstract(추상) 상태로 사용 시 구현이 필요 | |
* : 내부 클래스는 sealed class를 상속(extends) 필수, CounterMsg() | |
* */ | |
sealed class CounterMsg | |
object IncCounter : CounterMsg() // Object - 싱글톤 의미 | |
class GetCounter(val response: CompletableDeferred<Int>) : CounterMsg() // GetCounter클래스 (response 속성을 가짐) | |
fun main() { | |
runBlocking { | |
// 확장함수 counterActor() 호출 -> SendChannnel 반환 (counter = SendChannel) | |
val counter = counterActor() | |
GlobalScope.massiveRun { // 확장함수 massiveRun(), 인수가 action 하나뿐이라 소괄호'()' 생략 후 람다식으로 표현 | |
counter.send(IncCounter) // massiveRun함수 내부에서 action() 호출 시 실행될 부분 | |
} | |
// massiveRun이 끝난뒤 실행 | |
val response = CompletableDeferred<Int>() // CompletableDeferred<Int>란 지연가능한 실행객체로 Int를 반환한다는 의미 | |
counter.send(GetCounter(response)) // 채널을 통해 GetCounter(response)를 전송 | |
println("Counter = ${response.await()}") // 결과값 대기 await() | |
counter.close() // 채널(Channel) 닫기, close() 호출하면 채널을 통해 특별한 닫힘토큰이 전송됨 | |
} | |
} | |
// CoroutineScope 확장함수 선언, actor() 빌더 사용으로 SendChannel 인스턴스를 반환 | |
fun CoroutineScope.counterActor() = actor<CounterMsg> { | |
// actor 블록 내에 속성들은 로컬(지역) 변수로 사용됨 | |
var counter = 0 | |
// actor{} 블록 내부는 수신자(Receiver) 역할로, 채널 전부 순회를 위한 for-loop문 | |
for (msg in channel) { | |
// when을 이용해 채널을 통해 전송된 msg가 selaed Class 내부의 어떤 type인지 구분 | |
when (msg) { | |
is IncCounter -> counter++ // abstract(구현), IncCounter 타입이면 counter++ | |
is GetCounter -> msg.response.complete(counter) // GetCounter의 속성인 response의 값을 반환 | |
// complete() 함수? CompletableDeferred<Int>는 지연실행 가능한 객체로 타입은 Int이다. | |
// complete()는 실행한다는 의미인데 int값을 반환한다는 걸로 이해하면 된다 | |
} | |
} | |
} | |
// CoroutineScope 확장함수, 인수가 "action :suspend () -> Unit"으로 반환값이 없는 지연(suspend) 고차함수(high-order function) | |
suspend fun CoroutineScope.massiveRun(action: suspend () -> Unit) { | |
val n = 100 // 생성할 코루틴 개수, 로컬(지역) 변수 | |
val k = 1000 // 각 코루틴에서 반복 실행할 횟수 | |
val time = measureTimeMillis { | |
val jobs = List(n) { // List(100), 100개의 코루틴을 생성 반복 | |
launch { | |
repeat(k) { // repeat(1000), 코루틴 1개당 1000번 반복 실행 | |
action() // action 고차함수 실행 | |
} | |
} | |
} | |
jobs.forEach { it.join() } // 100개의 코루틴(jobs)를 하나씩 join() 종료 대기 | |
} | |
println("Completed ${n * k} actions in $time ms") // 코루틴이 모두 종료 되고나서 출력할 내용 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment