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의 주요 기능들을 모두 살펴보았습니다!
Originally published at https://dss99911.github.io
Top comments (0)