-
coroutine - launch, async, CoroutineContext개발 2023. 2. 28. 20:00
launch, async
coroutine을 시작하는 방법은 launch, async가 있다. launch는 결과값을 반환하지 않고 async는 await를 이용해서 결과값을 반환할 수 있다.
fun main() { ThreadTest().runCoroutine() } class ThreadTest { fun runCoroutine() = runBlocking { val jobs = ArrayList<Deferred<Int>>() (1..5).map { number -> val job = async { delay((Math.random() * 1000).toLong()) println("${Thread.currentThread().name} done, number: $number") increaseCounter() return@async number } jobs.add(job) } jobs.forEach { println("result: ${it.await()}") } } } ------------------------------------------------------------------------- main done, number: 3 main done, number: 1 result: 1 main done, number: 5 main done, number: 2 result: 2 result: 3 main done, number: 4 result: 4 result: 5
코드에서 async 를 사용한 코루틴은 number 값을 리턴하도록 했고 jobs 리스트에서 그 값을 출력하도록 했다. 그 결과 1 부터 5까지 출력되는 것을 확인 할 수 있다.
fun main() { ThreadTest().runCoroutine() } class ThreadTest { fun runCoroutine() = runBlocking { val jobs = ArrayList<Job>() (1..5).map { number -> val job = launch { delay((Math.random() * 1000).toLong()) println("${Thread.currentThread().name} done, number: $number") increaseCounter() } jobs.add(job) } jobs.forEach { it.start() } } } ------------------------------------------------------------------------- main done, number: 4 main done, number: 3 main done, number: 1 main done, number: 2 main done, number: 5
이번에는 async 대신 launch를 사용했다. launch로 코루틴을 선언하면 리턴값으로 Job을 받는다. jobs 변수에서 job 별로 start() 함수를 호출해 실행하도록 했더니 결과가 병렬적으로 처리되는 것을 확인 할 수 있었다.
CoroutineContext
그런데 출력 결과에서 신기한 점이 있다. 작업을 처리하는 쓰레드 이름이 모두 main으로 출력된 것이다. 코루틴을 실행할 때 CoroutineContext 를 정해주면 코루틴을 실행할 쓰레드를 지정할 수 있다. 코루틴 디스패쳐는 코루틴 작업을 특정 쓰레드 풀에 위임하고 실행한다. 작업에 따라서 쓰레드를 다르게 가져갈 수 있다.
fun main() { ThreadTest().runCoroutine2() } class ThreadTest { fun runCoroutine2() = runBlocking { launch { println("thread ${Thread.currentThread().name}") } launch(Dispatchers.Unconfined) { println("thread ${Thread.currentThread().name}") } launch(Dispatchers.Default) { println("thread ${Thread.currentThread().name}") } launch(newSingleThreadContext("MyOwnThread")) { println("thread ${Thread.currentThread().name}") } } } ------------------------------------------------------------------------- thread main thread DefaultDispatcher-worker-1 thread main thread MyOwnThread
launch에 CoroutineContext 옵션을 넣어서 코루틴을 실행하는 쓰레드를 변경할 수 있다. 그 결과 출력된 쓰레드 이름이 다른것을 확인할 수 있다.
'개발' 카테고리의 다른 글
Redis는 왜 다른 DB보다 빠를까 (0) 2023.03.16 coroutine - runBlocking, coroutineScope, suspend (1) 2023.02.28 kubernetes - readiness, livenesss, startup probe (0) 2023.02.28 Java - Thread start, run (0) 2023.02.28 Java - synchronized, wait, notify (0) 2023.02.28