✨ 오늘 공부한 것
- 알고리즘 N개의 최소공배수 풀이 - 스레드와 코루틴 개념 복습 - 개인 과제 lv3
강의를 듣던 중 코드에 갑자기 등장한 녀석이다.
companion object {
@Volatile private var instance: CashShop? = null
fun getInstance(): CashShop {
if(instance == null) {
synchronized(this) {
instance = CashShop()
}
}
return instance!!
}
}
@Volatile
은 변수 선언시 사용할 수 있고, 값을 메인 메모리에만 적재할 수 있게 해준다고 한다. 사용하지 않는 경우 스레드는 메인 메모리에서 읽어온 값을 CPU 캐시에 저장하게 되고, 각각의 스레드가 캐시한 값이 달라질 수 있다. 이걸 방지하기 위한 키워드이다.
스레드는 thread 키워드로 만들 수 있다! 여러 개 만들면 멀티 스레드가 되겠다.
thread(start = true) {
for(i in 1..10) {
println("Thread1: 현재 숫자는 ${i}")
// 비동기 함수
// 1초의 딜레이 추가
runBlocking {
launch {
delay(1000)
}
}
}
}
코루틴은 코루틴 객체를 생성해 만들 수 있다. 코루틴은 빌더라는 것과 같이 사용되는데, 대표적인 빌더로는 launch
와 async
가 있다.
💡
launch
vs.async
반환 값이 있는지의 여부로 구분한다. 둘 다 람다 함수의 형태이며,
async
함수는 마지막 구문의 실행 결과를 반환한다.
launch
: 반환 값이 없는 Job 객체async
: 반환값이 있는 Deffered 객체
// 코루틴 패키지 import 필요
import kotlinx.coroutines.*
// CoroutineScope: 사용 후 해제 필요
val scope = CoroutineScope(Dispatcher.Default)
// launch나 async라는 함수를 통해 새로운 코루틴을 생성할 수 있다.
val coroutineA = scope.launch { ... }
val coroutineB = scope.async { ... }
// 작업이 끝나면 해제해주어야 한다.
coroutineA.cancel()
// GlobalScope: 해제 필요 X
val coroutineC = GlobalScope.launch { ... }
// runBlocking을 사용하면 코루틴이 종료될 때까지 메인 루틴 대기
runBlocking {
launch {
for (i in 1..5) {
println(i)
}
}
}
// 혹은, Job의 실행이 끝날때까지 대기하는 join() 함수 사용 (야매임)
runBlocking {
// 코루틴의 결과값이 나올 때까지 대기
coroutineC.join()
}