• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 共享模块
2
3共享模块是进程内只会加载一次的模块,使用"use shared"这一指令来标记一个模块是否为共享模块。
4
5非共享模块在同一线程内只加载一次,而在不同线程中会加载多次,每个线程都会生成新的模块对象。因此,可以使用共享模块来实现进程单例。
6
7
8## 约束限制
9
10- "use shared"需要与"use strict"一样写在ArkTS文件顶层,写在import语句之后其他语句之前。
11
12  共享属性不具备传递性。非共享模块A即使引入了共享模块B,模块A也不会因此变成共享模块。
13
14
15- 共享模块只支持ets文件。
16
17- 共享模块内不允许使用side-effects-import。
18
19  共享模块在同一进程内只加载一次,可在不同线程间共享。<br/>
20  共享模块加载时,导入的非共享模块不会立刻加载。在共享模块内访问依赖的非共享模块导出变量时,会在当前线程懒加载对应的非共享模块,非共享模块在线程间是隔离的,不同线程访问时会进行至多一次的模块懒加载。<br/>
21  由于side-effects-import不涉及导出变量,所以永远不会被加载,因此不支持。
22
23  ```ts
24  // 不允许使用side-effects-import
25  import "./sharedModule"
26  ```
27
28- 共享模块导出的变量必须是可共享对象。
29
30  共享模块在并发实例间可共享,因此模块导出的所有对象必须是可共享的,可共享对象参考[Sendable规格](sendable-constraints.md)。
31
32- 共享模块不允许直接导出模块。
33
34  ```ts
35  // test.ets
36  export let num = 1;
37  export let str = 'aaa';
38
39  // 共享模块
40  'use shared'
41
42  export * from './test'; // 编译报错,不允许直接导出模块
43  export {num, str} from './test'; // 正确示例,导出对象合集
44  ```
45
46
47- 共享模块可以引用共享模块或非共享模块。共享模块的引用和被引用场景没有限制。
48
49- napi_load_module和napi_load_module_with_info支持加载共享模块。
50
51- 动态加载不支持加载共享模块。
52
53## 使用示例
54
551. 共享模块导出Sendable对象。
56
57   ```ts
58   // 共享模块sharedModule.ets
59   import { ArkTSUtils } from '@kit.ArkTS';
60
61   // 声明当前模块为共享模块,只能导出可Sendable数据
62   "use shared"
63
64   // 共享模块,SingletonA全局唯一
65   @Sendable
66   class SingletonA {
67     private count_: number = 0;
68     lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock()
69
70     public async getCount(): Promise<number> {
71       return this.lock_.lockAsync(() => {
72         return this.count_;
73       })
74     }
75
76     public async increaseCount() {
77       await this.lock_.lockAsync(() => {
78         this.count_++;
79       })
80     }
81   }
82
83   export let singletonA = new SingletonA();
84   ```
85
862. 在多个线程中操作共享模块导出的对象。
87
88   ```ts
89   import { taskpool } from '@kit.ArkTS';
90   import { singletonA } from './sharedModule';
91
92   @Concurrent
93   async function increaseCount() {
94     await singletonA.increaseCount();
95     console.info("SharedModule: count is:" + await singletonA.getCount());
96   }
97
98   @Concurrent
99   async function printCount() {
100     console.info("SharedModule: count is:" + await singletonA.getCount());
101   }
102
103   @Entry
104   @Component
105   struct Index {
106     @State message: string = 'Hello World';
107
108     build() {
109       Row() {
110         Column() {
111           Button("MainThread print count")
112             .onClick(async () => {
113               await printCount();
114             })
115           Button("Taskpool print count")
116             .onClick(async () => {
117               await taskpool.execute(printCount);
118             })
119           Button("MainThread increase count")
120             .onClick(async () => {
121               await increaseCount();
122             })
123           Button("Taskpool increase count")
124             .onClick(async () => {
125               await taskpool.execute(increaseCount);
126             })
127         }
128         .width('100%')
129       }
130       .height('100%')
131     }
132   }
133   ```
134