HarmonyOS 鸿蒙Next 异步锁问题

发布于 1周前 作者 yuanlaile 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 异步锁问题

关于异步锁,参照官方指南给的示例代码,测试代码如下:

@Sendable
export class A {
private count_: number = 0;
lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock();

public async getCount(): Promise<number> { // 对需要保护的数据加异步锁 return this.lock_.lockAsync(() => { return this.count_; }) }

public async increaseCount() { // 对需要保护的数据加异步锁 this.lock_.lockAsync(() => { this.count_++; }) } }

@Concurrent async function printCount(a: A) { await a.increaseCount(); console.info(“InputModule: count is:” + await a.getCount()); }

// 创建sendable对象a let a: A = new A(); // 将实例a传递给子线程 for (let i = 0; i < 10000; i++) { taskpool.execute(printCount, a); }

疑问

  • 预期最终的结果是10000,实际测试结果也是10000,但是中间有很多重复的数值,同样的测试案例,使用Android的线程锁就打印出来的都是连续的。
  • 官方指南给的代码中   taskpool.execute(printCount, a) 这一句前是有一个await关键字,加上这个以后即使不用线程锁,由于都是主线程的同步任务,结果也是正确的。

有没有懂哥给指点迷津?

2 回复

预期最终的结果是10000,实际测试结果也是10000 说明易步锁对数据起到了保护作用(如果没有起到保护作用,开10000个线程最终的结果肯定小于10000)

有很多重复的数值打印出来 说明打印的时候多个线程对同一个数值进行了打印 原因就出在累加的时候和打印的时候在2个不同的异步锁中 并不是加完就打印(没有保证原子性)  把console.log放在 increaseCount()里

  public async increaseCount() {
    // 对需要保护的数据加异步锁
    await this.lock_.lockAsync(() => {
      this.count_++;
      console.log("InputModule: count is:" + this.count_);
    })
  } 

那打印出来就是连续的 不会有重复值

针对HarmonyOS 鸿蒙Next异步锁问题,以下是一些专业的解答:

HarmonyOS 鸿蒙Next为了解决多并发实例间的数据竞争问题,引入了异步锁机制。这种异步锁是非阻塞式的,可以避免死锁问题,同时支持跨并发实例引用传递,提高了开发效率。

在使用异步锁时,需要注意以下几点:

  1. 异步锁的使用方法需要标记为async,调用方需要用await修饰调用,以保证时序正确。
  2. 异步锁的粒度必须足够小,避免多个并发实例长时间持有锁,导致死锁问题。
  3. 异步锁需要在代码执行完成后立即释放,避免内存泄漏。
  4. 如果需要使用多个锁,需要按照一定的顺序获取锁,同样是为了避免死锁问题。

如果在使用过程中遇到“锁超时”错误,可以尝试以下方法解决:

  1. 检查获取锁的代码逻辑,确认是否存在死锁的情况。
  2. 增加锁的超时时间设置,避免因为超时时间过短而导致的频繁超时错误。
  3. 分析程序中对锁的竞争情况,优化代码以减少锁的竞争。
  4. 检查系统资源是否紧张,如CPU、内存等,确保系统资源充足。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部