在 multiplatform Kotlin 代码中应该使用什么多平台锁或同步方法?以前在 Java 代码中我使用了
synchronized
,我也可以在 Kotlin 中看到synchronized
。然而,它被标记为已弃用,并将很快从 common
标准库中删除。
withLock
,但它只支持JVM,不支持多平台。
有什么想法吗?
附言。现在我们不想迁移到 Kotlin 协程,因为太多的重写和协程库占用空间(对于具有严格磁盘占用空间要求的 Android 库来说太大了)。
来自 Kotlin/Native 并发文档(这里):
Kotlin/Native 中的并发性
Kotlin/Native 运行时不鼓励具有互斥代码块和条件变量的经典面向线程的并发模型,因为众所周知这种模型容易出错且不可靠。相反,我们建议使用一系列替代方法,让您可以使用硬件并发并实施阻塞 IO。这些方法如下,将在以后的章节中详细说明:
- 传递消息的工人
- 对象子图所有权转移
- 对象子图冻结
- 对象子图分离
- 使用 C 全局变量的原始共享内存
- 阻塞操作的协程(本文未涉及)
似乎锁在 Kotlin/Native 中并没有被设计出来。有are实现(见Lock.kt),但是那个类被标记为
internal
.
但是,在KTOR中有锁的多平台实现(非常有限doc,源代码)。它是公开的,但带有
@InternalApi
,这可能会影响其稳定性。
您可能也对这个 KotlinLang 讨论主题感兴趣:同步的替换
Kotlin common 中没有锁也没有同步。 Kotlin 的做法是使用不可变数据。你可以在JVM Native中常见的和实际的实现中加入你自己的expect AtomicReference,会有很大的帮助。还要记住,Native 中的协程目前是单线程的。此外,您不能在 Native 中的线程之间共享可变状态。
最好的多平台解决方案是 kotlinx-atomicfu,它是 Kotlin 官方库的成员。
查看其锁定功能:
包提供多平台锁定原语,不需要对 Kotlin/JVM 和 Kotlin/JS 的额外运行时依赖,并带有 Kotlin/Native 的库实现kotlinx.atomicfu.locks
- SynchronizedObject 是为继承而设计的。
- ReentrantLock 是为委托而设计的。
虽然它目前处于测试阶段,但它已经被 kotlinx-coroutines 和 arrow-kt 等生产质量库使用。
不幸的是,它并不总是易于使用:因为它基于 Kotlin 编译器插件,所以它的版本绑定到特定的 Kotlin 版本。