Kotlin Native 동시성과 Freezing
Kotlin Native는 JVM과 다른 메모리 모델을 사용합니다. 멀티스레드 환경에서 안전하게 객체를 공유하기 위해 freezing 개념을 도입했습니다.
기본 개념
Object와 freeze
Object 선언은 기본적으로 freeze 상태입니다.
object MySingleton {
// 기본적으로 freeze됨
// mutable로 바꾸려면 @ThreadLocal 사용
}
Global Properties
전역 프로퍼티는 메인 스레드에서만 접근 가능하며 mutable입니다.
// 백그라운드 스레드에서 접근 시 에러:
// kotlin.native.IncorrectDereferenceException:
// Trying to access top level value not marked as
// @ThreadLocal or @SharedImmutable from non-main thread
String
String은 기본적으로 frozen 상태입니다.
freeze 발생 위치 추적
ensureNeverFrozen()을 사용하면 freeze가 발생하는 위치를 찾을 수 있습니다.
Object vs Property Freeze
freeze는 object에 걸리지, property에 걸리는 것이 아닙니다.
class A {
var b = B()
}
fun run() {
val a = A()
a.b.freeze()
a.b = B() // freeze 후에도 에러 없음! (a는 freeze되지 않음)
}
a.b가 바뀔 때 에러가 나게 하려면 a를 freeze해야 합니다.
ensureNeverFrozen과 sub-graph
ensureNeverFrozen은 해당 object에만 적용되고, 참조되는 하위 객체에는 반영되지 않습니다.
class A {
init {
ensureNeverFrozen()
}
var a = B("a")
}
fun run() {
A().a.freeze() // 에러가 안남 (B만 freeze됨)
}
람다와 Freeze
클래스 참조가 없는 경우
클래스 안에서 백그라운드 람다가 생성되더라도, 클래스 객체를 참조하지 않으면 클래스는 freeze되지 않습니다.
class CountingModelSafer {
var count = 0
fun increment() {
count++
saveToDb(count)
}
private fun saveToDb(arg: Int) = background {
// 클래스를 참조하지 않음
println("Doing db stuff with $arg, in main $isMainThread")
}
}
fun captureArgs() {
val model = CountingModelSafer()
model.increment() // count 변경 가능
println("I have ${model.count}")
model.increment()
println("I have ${model.count}")
}
클래스 참조가 있는 경우
람다에서 클래스 멤버를 참조하면 클래스가 freeze됩니다.
class CountingModel {
var count = 0
fun increment() {
count++
background {
saveToDb(count) // count는 CountingModel의 필드라 CountingModel을 freeze함
}
}
private fun saveToDb(arg: Int) {
println("Saving $arg to db")
}
}
Coroutine과 Freeze
coroutine을 launch한다고 자동으로 freeze되지는 않습니다.
Dispatcher가 다른 스레드를 사용하는 경우, Native에서는 kotlin.native.concurrent.Worker를 호출하고, 여기서 freeze가 발생합니다.
유용한 리소스
- Kotlin Native Concurrency
- Kotlin Native Immutability
- Touchlab - Kotlin Native Concurrency
- Kotlin Native Concurrency Hands-on
Kotlin Multiplatform
Kotlin Multiplatform에 대한 더 자세한 내용은 다음 리소스를 참고하세요:
다음 단계
Kotlin Native의 동시성에 대해 알아보았습니다. 이제 Kotlin의 주요 기능들을 모두 살펴보았습니다!
Comments