리엑티브 프로그래밍의 정의

  • 데이터 스트림과 변경 사항 전파를 중심으로 하는 비동기 프로그래밍 패러다임

코루틴이란?

리엑티브 프로그래밍중 하나, 동시성 프로그래밍을 지원한다.

  • 동시성 프로그래밍이란? → 여러개의 작업이 동시에 진행되는것이 아닌, 여러개의 작업이 매우 빠르게 하나의 작업에 적재되어 실행되는것을 말함.

코루틴 Features

Coroutines is our recommended solution for asynchronous programming on Android. Noteworthy features include the following:

  • Lightweight: You can run many coroutines on a single thread due to support for suspension, which doesn't block the thread where the coroutine is running. Suspending saves memory over blocking while supporting many concurrent operations.
  • Fewer memory leaks: Use structured concurrency to run operations within a scope.
  • Built-in cancellation supportCancellation is propagated automatically through the running coroutine hierarchy.
  • Jetpack integration: Many Jetpack libraries include extensions that provide full coroutines support. Some libraries also provide their own coroutine scope that you can use for structured concurrency.

코루틴이 스레드에 비해 경량적인 이유?

  • Dispatcher를 어떤것으로 정했느냐에 따라 다르지만, 스레드풀을 사용함으로서 최소한의 context switching이 일어나며, 내부적으로 continuation을 저장할 heap 메모리 할당만으로 작업을 기록하기 때문에 쓰레드 전환에 비해서 자원을 많이 아낄 수 있다.

 

Continuation이란?

interface Continuation<in T> {
	val context: CoroutineContext
	fun resume(value: T)
	fun resumeWithException(exception: Throwable)
}

 

위와 같은 인터페이스이다. 그리고 coroutine이 실행될때 CPS(continuation Passing Style)로 아래와 같이 변환되어 실행된다.

suspen fun postItem(item: Item) {
↛       val token = requestToken()
↛       val post = createPost(token, item)
        processPost(post)
    }
fun postItem(item: Item, cont: Continuation) {
    val sm = object : CoroutineImpl { … }
    switch (sm.label) {
        case 0:
            val token = requestToken(sm)
        case 1:
            val post = createPost(token, item, sm)
        case 2:
            processPost(post)
    }
}

위처럼 거대한 switch문으로 실행됨. 

 

 

Current 스레드를 사용할 경우

Default Thread Pool 이 사용되는것을 알 수 있다

@Test
fun testSimpleCoroutine() {
   var i: Int = 0
   repeat(10) {
      GlobalScope.launch {
         println("${++i}: ${Thread.currentThread().name}")
      }
   }
   Thread.sleep(100)
}

 

메인스레드를 사용할 경우 

@Test
fun testSimpleCoroutineThreadMain() {
   var i: Int = 0
   repeat(10) {
      GlobalScope.launch(Dispatchers.Unconfined) {
         i++
         println("$i: ${Thread.currentThread().name}")
      }
   }
   Thread.sleep(100)
}

메인 스레드에서 코루틴이 하나씩 실행되는 것을 알 수 있다.

 

 

Reference

https://myungpyo.medium.com/코루틴-공식-가이드-자세히-읽기-part-1-dive-2-25b21741763a

 

코루틴 공식 가이드 자세히 읽기 — Part 1 — Dive 2

코루틴은 왜 스레드 보다 가볍다고 할까?

myungpyo.medium.com

https://piotrminkowski.com/2020/06/23/kotlin-coroutines-vs-java-threads/

 

Kotlin Coroutines vs Java Threads - Piotr's TechBlog

Showing differences between Kotlin coroutines and Java threads. Explaining Kotlin coroutine threading model in JUnit tests.

piotrminkowski.com

https://www.youtube.com/watch?v=YrrUCSi72E8&t=110s

 

728x90
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기