如何在Kotlin中创建Arrow Atomic类型的类成员变量
Arrow-fx Atomic 作为类成员变量的实现方案
Arrow-fx 的 Atomic 类型与 Java AtomicRef 类似,自带初始值,访问时无需做空检查,但它只能在挂起函数内初始化。以下是几种将其作为类成员变量使用的可行方案:
方案一:延迟初始化 + 挂起初始化方法
通过 lateinit 声明变量,再在挂起函数中完成初始化,需确保调用业务方法前先执行初始化:
import arrow.fx.coroutines.Atomic class Counter { private lateinit var count: Atomic<Int> suspend fun init() { count = Atomic(0) } suspend fun increment() { count.update(Int::inc) } suspend fun getCount(): Int { return count.get() } } // 使用示例 suspend fun main() { val counter = Counter() counter.init() // 必须先调用初始化 (0 until 20_000).parTraverse { counter.increment() } println(counter.getCount()) }
注意:如果未调用
init()就访问count,会抛出UninitializedPropertyAccessException。
方案二:通过 runBlocking 同步初始化
利用 runBlocking 在类初始化阶段同步创建 Atomic 实例,适合应用启动等低频率初始化场景,避免高频使用时的线程阻塞:
import arrow.fx.coroutines.Atomic import kotlinx.coroutines.runBlocking class Counter { private val count: Atomic<Int> = runBlocking { Atomic(0) } suspend fun increment() { count.update(Int::inc) } suspend fun getCount(): Int { return count.get() } } // 使用示例 suspend fun main() { val counter = Counter() (0 until 20_000).parTraverse { counter.increment() } println(counter.getCount()) }
方案三:绑定协程作用域初始化
将 Atomic 的初始化与类所属的协程作用域绑定,符合协程编程最佳实践,避免线程阻塞:
import arrow.fx.coroutines.Atomic import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob class Counter(scope: CoroutineScope) { private val count: Atomic<Int> = scope.run { Atomic(0) } suspend fun increment() { count.update(Int::inc) } suspend fun getCount(): Int { return count.get() } } // 使用示例 fun main() = runBlocking { val counter = Counter(this) (0 until 20_000).parTraverse { counter.increment() } println(counter.getCount()) }
内容的提问来源于stack exchange,提问作者Vencat
相关产品推荐
相关产品推荐

