출처: https://www.boostcourse.org/mo234/lecture/154329?isDesc=false
기능 | 설명 |
---|---|
launch, async | 코루틴 빌더 |
Job, Deferred | cancellation 지원을 위한 기능 (Job은 생명주기를 갖고 동작하는 작업의 단위) |
Dispatchers | 일종의 스케줄러, Default는 백그라운드 코루틴을 위해, Main은 Android, Swing, JavaFX를 위해 사용됨. |
delay, yield | 상위 레벨 지연 (suspending) 함수 |
Channel, Mutex | 통신과 동기화를 위한 기능 |
coroutineScope, supervisorScope | 범위 빌더 |
select | 표현식 지원 |
기능 | 설명 |
---|---|
CommonPool | 코루틴 컨텍스트 |
produce, actor | 코루틴 빌더 |
📌 코루틴 라이브러리 추가하기
File > Project Structures > Libraries > From Maven >org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:version
추가
cf) https://stackoverflow.com/questions/52522282/using-kotlinx-coroutines-in-intellij-idea-project
package chap06.section2
import kotlinx.coroutines.*
fun main() { // 메인 스레드의 컨텍스트
GlobalScope.launch { // 새로운 코루틴을 백그라운드에서 실행
delay(1000L) // 1초 넌블로킹 지연
print("World!") // 지연 후 출력
}
print("Hello, ") // 코루틴이 지연되는 동안 메인 스레드는 계속 실행
Thread.sleep(2000L) // 메인 스레드가 JVM에 의해 바로 종료되지 않도록 2초 지연
}
Hello, World! (Hello, 가 출력되고 1초 뒤에 World! 가 출력됨.)
public suspend fun delay(timeMills: kotlin.Long): kotlin.Unit { /* compiled code */ }
package chap06.section2
import kotlinx.coroutines.*
fun main() { // 메인 스레드의 컨텍스트
//doSomething() // error
GlobalScope.launch { // 새로운 코루틴을 백그라운드에서 실행
delay(1000L) // 1초 넌블로킹 지연
print("World!") // 지연 후 출력
doSomething() // ok
}
print("Hello, ") // 코루틴이 지연되는 동안 메인 스레드는 계속 실행
Thread.sleep(2000L) // 메인 스레드가 JVM에 의해 바로 종료되지 않도록 2초 지연
}
suspend fun doSomething() {
println("Do something!")
}
package chap06.section2
import kotlinx.coroutines.*
fun main() {
val job = GlobalScope.launch {
delay(1000L)
println("World")
doSomething()
}
println("Hello")
println("job: $job")
Thread.sleep(2000L)
println("job: $job")
}
suspend fun doSomething() {
println("Do something")
}
Hello
job: StandaloneCoroutine{Active}@5b1d2887
World
Do something
job: StandaloneCoroutine{Completed}@5b1d2887
package chap06.section2
import kotlinx.coroutines.*
fun main() {
val job = GlobalScope.launch {
delay(1000L)
println("World")
doSomething()
}
println("Hello")
println("job: ${job.isActive}, ${job.isCompleted}")
Thread.sleep(2000L)
println("job: ${job.isActive}, ${job.isCompleted}")
}
suspend fun doSomething() {
println("Do something")
}
Hello
job: true, false
World
Do something
job: false, true
package chap06.section2
import kotlinx.coroutines.*
fun main() {
runBlocking {
val job = GlobalScope.launch {
delay(1000L)
println("World")
doSomething()
}
println("Hello")
println("job: ${job.isActive}, ${job.isCompleted}")
//Thread.sleep(2000L)
job.join()
println("job: ${job.isActive}, ${job.isCompleted}")
}
}
suspend fun doSomething() {
println("Do something")
}
Hello
job: true, false
World
Do something
job: false, true
package chap06.section2
import kotlinx.coroutines.*
fun main() {
runBlocking {
val job = GlobalScope.launch {
delay(1000L)
println("World")
doSomething()
}
println("Hello")
println("job: ${job.isActive}, ${job.isCompleted}")
//Thread.sleep(2000L)
//job.join()
println("job: ${job.isActive}, ${job.isCompleted}")
}
}
suspend fun doSomething() {
println("Do something")
}
Hello
job: true, false
job: true, false
join()을 해주지 않으면 코루틴의 작업이 완료될 때까지 기다리지 않고, 메인 스레드가 계속 실행되기 때문에 위와 같은 결과가 나오고 프로그램이 종료된다.
package chap06.section2
import kotlinx.coroutines.*
suspend fun doWork1(): String {
delay(1000)
return "Work1"
}
suspend fun doWork2(): String {
delay(3000)
return "Work2"
}
private fun workInSerial(){
GlobalScope.launch {
// 코루틴 내의 suspend 함수는 순차적으로 실행됨.
val one = doWork1()
val two = doWork2()
// 1초, 3초 지나고나서 출력
println("Kotlin one: $one")
println("Kotlin two: $two")
}
}
fun main() {
workInSerial()
readLine() // 메인 스레드가 먼저 종료되는 것을 막기 위해 콘솔에서 입력 대기
}
package chap06.section2
import kotlinx.coroutines.*
suspend fun doWork1(): String {
delay(1000)
return "Work1"
}
suspend fun doWork2(): String {
delay(3000)
return "Work2"
}
private fun workInSerial(): Job {
val job = GlobalScope.launch {
// 코루틴 내의 suspend 함수는 순차적으로 실행됨.
val one = doWork1()
val two = doWork2()
// 1초, 3초 지나고나서 출력
println("Kotlin one: $one")
println("Kotlin two: $two")
}
return job
}
fun main() {
runBlocking {
val job = workInSerial()
job.join()
}
//readLine()
}
Kotlin one: Work1
Kotlin two: Work2
package chap06.section2
import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis
suspend fun doWork1(): String {
delay(1000)
return "Work1"
}
suspend fun doWork2(): String {
delay(3000)
return "Work2"
}
private fun workInSerial(): Job {
val job = GlobalScope.launch {
// 코루틴 내의 suspend 함수는 순차적으로 실행됨.
val one = doWork1()
val two = doWork2()
// 1초, 3초 지나고 나서 출력
println("Kotlin one: $one")
println("Kotlin two: $two")
}
return job
}
fun main() {
runBlocking {
val time = measureTimeMillis {
val job = workInSerial()
job.join()
}
println("time: $time")
}
}
Kotlin one: Work1
Kotlin two: Work2
time: 4077
실행 시간을 보면, doWork1()과 doWork2()가 순차적으로 실행되었다는 걸 알 수 있다. 그렇다면, 특정 suspend 함수들을 비동기적으로 동시에 실행할 수는 없을까?
package chap06.section2
import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis
suspend fun doWork1(): String {
delay(1000)
return "Work1"
}
suspend fun doWork2(): String {
delay(3000)
return "Work2"
}
private fun workInSerial(): Job {
val job = GlobalScope.launch {
// 코루틴 내의 suspend 함수는 순차적으로 실행됨.
val one = doWork1()
val two = doWork2()
// 1초, 3초 지나고 나서 출력
println("Kotlin one: $one")
println("Kotlin two: $two")
}
return job
}
private fun workInParallel(): Job {
val one = GlobalScope.async {
doWork1()
}
val two = GlobalScope.async {
doWork2()
}
val job = GlobalScope.launch {
// one, two가 동시에 실행됨.
val combined = one.await() + "_" + two.await()
println("Kotlin Combined: $combined")
}
return job
}
fun main() {
runBlocking {
val time = measureTimeMillis {
val job = workInParallel()
job.join()
}
println("time: $time")
}
}
Kotlin Combined: Work1_Work2
time: 3080
doWork1()과 doWork2()가 비동기적으로 동시에 실행되어서 실행 시간이 3초 정도로 나온 것을 볼 수 있다.