fun main() {
thread(start = true) {
for (i in 1..5) {
println("Thread1 : ${i}")
runBlocking {
launch {
delay(1000)
}
}
}
}
thread(start = true) {
for (i in 50..55) {
println("Thread2 : ${i}")
runBlocking {
launch {
delay(1000)
}
}
}
}
}
Thread1 : 1
Thread2 : 50
Thread2 : 51
Thread1 : 2
Thread1 : 3
Thread2 : 52
Thread1 : 4
Thread2 : 53
Thread2 : 54
Thread1 : 5
Thread2 : 55
코루틴(Coroutine)은 빌더와 함께 사용한다.
launch
와 async
빌더를 가장 많이 사용한다.launch는 결과 값이 없는 코루틴 빌더를 의미한다. Job 객체를 바놘하며 이를 통해 상태를 관리한다.
async는 결과 값이 있는 코루틴 빌더를 의미한다. Deferred 타입으로 값을 반환하며 이를 통해 상태 관리와 결과 값에 접근할 수 있다. 결과 값은 await() 함수를 통해 접근할 수 있다.
코루틴은 스코프로 범위를 지정할 수 있다.
GlobalScope : 앱이 실행 된 이후에 계속 수행 되어야 할 때 사용한다.
CoroutineScope : 필요할 때만 생성하고 사용 후에 정리가 필요하다.
코루틴을 실행 할 Thread를 Dispatcher
로 지정할 수 있다.
Dispatchers.Main : UI와 상호작용 하기 위한 메인 쓰레드
Dispatchers.IO : 네트워크나 디스크 I/O 작업에 최적화 되어 았는 쓰레드
Dispatchers.Default : 기본적으로 CPU 작업에 최적화 되어 있는 쓰레드
val job = GlobalScope.launch { // 백그라운드에서 비동기적으로 수행 된다.
delay(3000)
println("Coroutine:: GlobalScope")
}
val job = CoroutineScope(Dispatchers.Default).launch {
delay(3000)
println("Coroutine:: CoroutineScope")
}
println("End Thread")
job.cancel() // 사용이 끝나면 해제 해줘야 한다.
async
는 Deferred
타입으로 값을 반환하며 이를 통해 상태 관리와 결과 값에 접근할 수 있다. await()
함수를 통해 접근할 수 있다. fun main() {
val job = CoroutineScope(Dispatchers.Default).launch {
val fileDownloadCoroutine = async(Dispatchers.IO) {
delay(10000)
"File download completed"
}
val databaseConnectCoroutine = async(Dispatchers.IO) {
delay(5000)
"Database connection completed"
}
println(fileDownloadCoroutine.await())
println(databaseConnectCoroutine.await())
}
println("End Main Thread")
job.cancel()
}