반응형
[Kotlin] 코루틴 Coroutine 사용법 및 개념 정리 - runBlocking - 2편
이전 포스트:[Kotlin] 코루틴 Coroutine 사용법 및 개념 정리 - GlobalScope, Delay, Dispatcher, Coroutine Context - 1편
runBlocking
- 저번 포스트에서 GlobalScope안에 썼었던 delay는 main Thread를 멈추지 않는 걸 확인했습니다.
- 그런데 mainThread를 멈출수있는 방법이 있습니다. 바로 runBlocking을 사용해주면 됩니다.
- 그럼 runBlocking은 언제 쓸까요? onCreate에서 delay를 쓸 수 없습니다. 그런데 만약 onCreate에서 일어나는 UI 업데이트에 delay를 넣어주고 싶을 때 runBlocking안에 delay를 넣어 쓸 수 있습니다.
- runBlocking은 다양하게 쓸 수 있습니다.
class MainActivity : AppCompatActivity() {
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//a. GlobalScope 예시
GlobalScope.launch(Dispatchers.Main){
Log.d(TAG, "1a")
delay(1000L)
Log.d(TAG, "2a")
}
Log.d(TAG, "3a")
//b. RunBlocking 예시
runBlocking {
Log.d(TAG, "1b")
delay(1000L) //여기서 delay를 실행시키면 UI업데이트를 모두 block 하게 됩니다.
Log.d(TAG, "2b")
}
Log.d(TAG, "3b")
}
}
- 위 코드를 실행시켜보면 a.Globalscope은 3a, 1a동시 (1초 후)-> 2a 순서로 로그가 찍히게 됩니다.
- b. Runblocking에서는1b(1초 후) -> 2b->3b 순서로 로그가 찍히게 됩니다.
- 이렇게 RunBlocking의 역할은 sleep역할과 비슷한데 RunBlocking을 써야 하는 이유는 무엇일까요?
runBlocking을 써야하는 이유
- 아래와 같이 runBlocking은 sleep과 똑같은 결과물을 가져옵니다.
//using Thread.sleep
class MainActivity : AppCompatActivity() {
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("TAG", "Before Sleep")
Thread.sleep(2000L)
Log.d("TAG", "End Sleep")
}
}
//using runBlocking
class MainActivity : AppCompatActivity() {
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("TAG", "Before Sleep")
runBlocking{
delay(1000L)
}
Log.d("TAG", "End Sleep")
}
}
- 결과가 같아도 runBlocking 쓰는 이유는 우선 runBlocking은 CoroutineScope 중 하나입니다. 그러므로 runBlocking안에서 다른 스레드를 실행할 수 있습니다.
runBlocking {
launch(Dispatchers.IO) { //launch를 실행할때 GlobalScope가 필요없습니다 왜냐하면
//이미 runBlocking이 CoroutineScope이기 때문입니다.
delay(3000L)
Log.d("TAG","1a")
}
launch(Dispatchers.IO) {
delay(3000L)
Log.d("TAG","1b")
}
}
- 이렇게 코드를 실행하게 되면 runblocking이 실행되고 로그 1a와 1b가 동시에 실행되게 됩니다. 동시에 실행됐다는 것은 멀티 스레드가 작동했다는 것을 알 수 있습니다.
참고자료
다음포스트에서는 coroutine에서 자주쓰이는 Join, repeat,cancel을 다뤄보겠습니다.
반응형