在这里插入图片描述

本文是 KMP 三方库鸿蒙化适配,聚焦 kotlinx-atomicfu(Kotlin 官方原子变量库)的 OpenHarmony 适配。我们只讲本仓库真实落地的代码,不做系列横向对比。

目录

摘要

本文是 KMP 三方库鸿蒙化适配系列的一部分,聚焦 Kotlin 官方原子变量库 kotlinx-atomicfu 在 OpenHarmony 上的适配实践。文章采用「纯语义复刻、零 @kit」的三层架构路线:语义层用 ArkTS 实现 AtomicInt / AtomicLong / AtomicBoolean / AtomicRef 的原子读写与 CAS 循环;引擎层以纯复刻工厂 + 并发语义验证的方式提供能力;验收页在真机上验证 1000 次并发自增、CAS 期望值校验与引用交换。文章最后总结了四条踩坑经验,并附上社区与源码链接。

一、为什么选它

kotlinx-atomicfu 是 Kotlin 官方的原子变量库,核心价值是「无锁(lock-free)地操作共享可变状态」:AtomicInt / AtomicLong / AtomicBoolean / AtomicRef + incrementAndGet / compareAndSet 等。它是 kotlinx-coroutines 等并发库的底层基石。

到了 OpenHarmony,ArkTS 是单线程 Actor 模型,原生没有原子变量;但这不代表不能「等价复刻」——原子变量的语义(CAS 循环、期望值校验、引用交换)完全可以忠实保留,让 KMP 源码里 atomic(initial) 的写法在鸿蒙侧有一一对应的实现。这也是本系列「纯语义复刻」路线的又一次实践。

二、适配总思路:三层架构(纯语义复刻,零 @kit)

  1. 语义层(零 @kit.*):AtomicInt / AtomicLong / AtomicBoolean / AtomicRef 只做原子读写 + CAS 循环,不碰任何平台 API。
  2. 引擎层(无系统桥接):OhosAtomicfuEngine 承担「工厂 + 并发语义验证」,与系列中 kotlinx-collections-immutable 的纯逻辑引擎层定位一致。
  3. 验收页:AtomicfuDemo 在真机/模拟器上做 1000 次逻辑并发自增、CAS 期望校验、AtomicRef 引用交换。

三、语义层:CAS 循环是灵魂

Atomicfu.ets 只用 number / boolean / 泛型引用,零平台依赖(注意 ArkTS 严格模式禁止构造参数属性,字段显式赋值):

export class AtomicInt {
  private value: number;
  constructor(initial: number) { this.value = initial; }

  /** 原子自增并返回新值(CAS 循环,lock-free 语义) */
  incrementAndGet(): number {
    let prev: number;
    do {
      prev = this.value;
    } while (!this.compareAndSet(prev, prev + 1));
    return this.value;
  }

  /** 经典 CAS:期望值命中才更新 */
  compareAndSet(expect: number, update: number): boolean {
    if (this.value === expect) {
      this.value = update;
      return true;
    }
    return false;
  }
}

要点:

  • lock-free 形态保留:incrementAndGet 用 do…while + compareAndSet 的循环实现,与 JVM 上 atomicfu 生成的 CAS 循环一一对应。虽然 ArkTS 单线程下不会真的竞争,但 API 形态与无锁算法被忠实保留。
  • AtomicRef<T> 引用语义:CAS 以引用相等判定(与 Java AtomicReference 一致),适合交换不可变对象。
  • AtomicLong 用 number 承载:ArkTS number 是 double,可精确表示至 2^53,足够覆盖 long 语义。

四、引擎层:工厂 + 并发语义验证

OhosAtomicfuEngine.ets 是纯复刻库,没有 HarmonyOS 专属系统能力可桥接,因此只做两件事:

export class OhosAtomicfuEngine {
  atomicInt(init: number): AtomicInt { return new AtomicInt(init); }

  /** 模拟 N 次逻辑并发自增,CAS 下最终值必须恒等于 N */
  benchConcurrentAdds(counter: AtomicInt, iterations: number): { finalValue: number; expected: number; consistent: boolean } {
    for (let i = 0; i < iterations; i++) counter.incrementAndGet();
    const finalValue = counter.get();
    return { finalValue, expected: iterations, consistent: finalValue === iterations };
  }
}

这印证了适配策略选择:纯算法/数据结构类库,引擎层可以是「纯复刻工厂 + 能力验证」,不必强行桥接系统 API。

五、验收页:真机上验证

AtomicfuDemo.ets 三个按钮:

  • 1000 次并发自增:对 AtomicInt(0) 跑 1000 次 incrementAndGet,结果区显示 最终值 = 1000,期望值 = 1000,CAS 一致 = 是——证明无锁自增语义正确。
  • CAS 期望值校验:AtomicInt(10) 先 compareAndSet(10,20) 成功,再 compareAndSet(10,30) 失败(值已变 20),结果区显示两次调用的成败与当前值。
  • AtomicRef 引用交换:AtomicRef<{count}> 用 compareAndSet(旧引用, 新引用) 交换对象,证明引用级 CAS 生效。

测试运行效果,结果区会显示稳定的原子语义结果,证明 kotlinx-atomicfu 的能力在鸿蒙真实可用。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

六、踩坑小结

  1. 不要因为 ArkTS 单线程就删掉 CAS 循环:保留 do…while + compareAndSet 才能与上游语义对齐,也方便后续迁移到多线程 Worker 场景。
  2. 严格模式禁止构造参数属性:constructor(initial: number) 内必须显式 this.value = initial,不能写成 constructor(private value: number)。
  3. AtomicRef 用引用相等:CAS 的 expect 必须传「同一引用」,传字面量 {count:1} 会永远不相等。
  4. long 语义边界:number 精确范围 2^53,超出需用大整数方案(见本系列第 28 篇 kotlinx-bignum)。

总结

本文完整记录了 kotlinx-atomicfu 在 OpenHarmony 上的适配过程,核心结论如下:

  1. 适配路线:采用「纯语义复刻」策略,不依赖任何 @kit.* 平台 API,通过三层架构(语义层、引擎层、验收页)实现与上游语义的一一对应。
  2. 语义层是灵魂:AtomicInt 等类用 do…while + compareAndSet 保留 lock-free 形态,AtomicRef 以引用相等判定 CAS,AtomicLong 用 number 承载(精确至 2^53)。
  3. 引擎层定位:纯算法/数据结构类库无需强行桥接系统 API,引擎层只需「纯复刻工厂 + 能力验证」。
  4. 验收验证:通过 1000 次并发自增、CAS 期望校验、引用交换三个按钮,在真机/模拟器上证明原子语义真实可用。
  5. 踩坑要点:不要因单线程删掉 CAS 循环、严格模式禁止构造参数属性、AtomicRef 必须传同一引用、long 语义有 2^53 边界。

社区引导

欢迎加入 KMP&CMP 鸿蒙社区:https://atomgit.com/CPF-KMP-CMP

本适配全部源码已开源在 AtomGit:https://atomgit.com/wdracky/kmp-ohos-adapters/tree/main/kotlinx-atomicfu

如果你在适配过程中用到了 AI 辅助工具,推荐码道(AtomCode)专属通道
https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwatomgit1&sourcead=dmzntgwatomgiths

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐