1# 异步锁
2
3为了解决多线程并发任务间的数据竞争问题,ArkTS引入了异步锁能力。异步锁可能会被类对象持有,因此为了更方便地在并发实例间获取同一个异步锁对象,[AsyncLock对象](../reference/apis-arkts/js-apis-arkts-utils.md#asynclock)支持跨线程引用传递。
4
5由于ArkTS语言支持异步操作,阻塞锁容易产生死锁问题,因此在ArkTS中仅支持异步锁(非阻塞式锁)。同时,异步锁还可以用于保证单线程内的异步任务时序一致性,防止异步任务时序不确定导致的同步问题。
6
7更多异步锁相关接口,可见[异步锁ArkTSUtils.locks](../reference/apis-arkts/js-apis-arkts-utils.md#arktsutilslocks)。
8
9> **说明:**
10>
11> 使用异步锁的方法需要标记为async,调用方需要使用await修饰,才能保证时序正确。
12
13## 使用示例
14
15为了解决[@Sendable共享对象](arkts-sendable.md)在不同线程修改共享变量导致的竞争问题,可以采用异步锁进行数据保护。示例如下:
16
17```ts
18import { ArkTSUtils, taskpool } from '@kit.ArkTS';
19
20@Sendable
21export class A {
22  private count_: number = 0;
23  lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock();
24
25  public async getCount(): Promise<number> {
26    // 对需要保护的数据加异步锁
27    return this.lock_.lockAsync(() => {
28      return this.count_;
29    })
30  }
31
32  public async increaseCount() {
33    // 对需要保护的数据加异步锁
34    await this.lock_.lockAsync(() => {
35      this.count_++;
36    })
37  }
38}
39
40@Concurrent
41async function printCount(a: A) {
42  console.info("InputModule: count is:" + await a.getCount());
43}
44
45@Entry
46@Component
47struct Index {
48  @State message: string = 'Hello World';
49
50  build() {
51    RelativeContainer() {
52      Text(this.message)
53        .id('HelloWorld')
54        .fontSize(50)
55        .fontWeight(FontWeight.Bold)
56        .alignRules({
57          center: { anchor: '__container__', align: VerticalAlign.Center },
58          middle: { anchor: '__container__', align: HorizontalAlign.Center }
59        })
60        .onClick(async () => {
61          // 创建sendable对象a
62          let a: A = new A();
63          // 将实例a传递给子线程
64          await taskpool.execute(printCount, a);
65        })
66    }
67    .height('100%')
68    .width('100%')
69  }
70}
71```
72