Kotlin/Native 中的不可变性

Kotlin/Native 实现了严格的可变性检测,确保了重要的不变式:对象要么不可变,要么在同一时刻只在单个线程中访问(mutable XOR global)。

在 Kotlin/Native 中不可变性是运行时属性,可以将 kotlin.native.concurrent.freeze 函数应用到任意对象子图。 它使从给定的对象递归可达的所有对象都不可变, 这样的转换是单向操作(即这些对象之后不能解冻)。 一些天然不可变的对象(如 kotlin.Stringkotlin.Int 与其他原生类型,以及 AtomicIntAtomicReference) 默认就是冻结的。如果对已冻结对象应用了修改操作, 那么会抛出 InvalidMutabilityException 异常。

为了实现 mutable XOR global 不变式,所有全局可见状态(目前有 object 单例与枚举)都会自动冻结。如果对象无需冻结,可以使用 kotlin.native.ThreadLocal 注解,这会使该对象状态成为线程局部的,因此可修改(但是变更后的状态对其他线程不可见)。

非基本类型的顶层/全局变量默认只能在主线程(即首先初始化 Kotlin/Native 运行时的线程)中访问。 在其他线程中访问会引发 IncorrectDereferenceException 异常。 如需其他线程可访问这种变量,可以使用 @ThreadLocal 注解将该值标记为线程局部,或者使用 @SharedImmutable 注解,它会冻结该值并使其他线程可访问。

AtomicReference 类可用于将变更后的冻结状态发布给其他线程,从而构建共享缓存等模式。