• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Shared Module
2
3A shared module, marked with **use shared**, is loaded only once in a process.
4
5A non-shared module is loaded once in the same thread and multiple times in different threads, creating a new module object in each thread. Shared modules, however, can be used to implement process-wide singletons.
6
7
8## Constraints
9
10- Similar to **use strict**, **use shared** must be placed at the top level of ArkTS files and should appear after **import** statements but before any other code.
11
12  The shared property cannot be passed on. That is, importing a shared module does not make a non-shared module shared.
13
14
15- Shared modules are only supported in .ets files.
16
17- **side-effects-import** is not allowed in shared modules.
18
19  A shared module is loaded only once within a single process and can be used across multiple threads.
20
21  When a shared module is loaded, non-shared modules that it imports are not loaded immediately. Instead, these non-shared modules are lazy-imported within the current thread when their exported variables are accessed. This lazy loading ensures that non-shared modules remain isolated between threads, with each thread potentially loading the module once if needed.
22
23  side-effects-import, which does not involve exported variables, is never loaded and therefore is not supported.
24
25  ```ts
26  // side-effects-import is not allowed.
27  import "./sharedModule"
28  ```
29
30- All variables exported by shared modules must be Sendable objects.
31
32  Since shared modules are shared across concurrent instances, all exported objects must be Sendable. For details, see [Usage Rules and Constraints for Sendable](sendable-constraints.md).
33
34- Modules cannot be directly exported from a shared module.
35
36  ```ts
37  // test.ets
38  export let num = 1;
39  export let str = 'aaa';
40
41  // Shared module
42  'use shared'
43
44  export * from './test'; // A compile-time error is reported. The module cannot be directly exported.
45  export {num, str} from './test'; // Correct example. Export the object set.
46  ```
47
48
49- Shared modules can import or be imported by both shared and non-shared modules. There are no restrictions on importing or being imported by shared modules.
50
51- **napi_load_module**, **napi_load_module_with_info**, and dynamic loading do not support loading of shared modules.
52
53
54## Usage Example
55
561. Export a Sendable object from a shared module.
57
58   ```ts
59   // Shared module sharedModule.ets
60   import { ArkTSUtils } from '@kit.ArkTS';
61
62   // Declare the current module as shared. Only Sendable data can be exported.
63   "use shared"
64
65   // Shared module. SingletonA is globally unique.
66   @Sendable
67   class SingletonA {
68     private count_: number = 0;
69     lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock()
70
71     public async getCount(): Promise<number> {
72       return this.lock_.lockAsync(() => {
73         return this.count_;
74       })
75     }
76
77     public async increaseCount() {
78       await this.lock_.lockAsync(() => {
79         this.count_++;
80       })
81     }
82   }
83
84   export let singletonA = new SingletonA();
85   ```
86
872. Operate an object exported from the shared module across multiple threads.
88
89   ```ts
90   import { taskpool } from '@kit.ArkTS';
91   import { singletonA } from './sharedModule';
92
93   @Concurrent
94   async function increaseCount() {
95     await singletonA.increaseCount();
96     console.info("SharedModule: count is:" + await singletonA.getCount());
97   }
98
99   @Concurrent
100   async function printCount() {
101     console.info("SharedModule: count is:" + await singletonA.getCount());
102   }
103
104   @Entry
105   @Component
106   struct Index {
107     @State message: string = 'Hello World';
108
109     build() {
110       Row() {
111         Column() {
112           Button("MainThread print count")
113             .onClick(async () => {
114               await printCount();
115             })
116           Button("Taskpool print count")
117             .onClick(async () => {
118               await taskpool.execute(printCount);
119             })
120           Button("MainThread increase count")
121             .onClick(async () => {
122               await increaseCount();
123             })
124           Button("Taskpool increase count")
125             .onClick(async () => {
126               await taskpool.execute(increaseCount);
127             })
128         }
129         .width('100%')
130       }
131       .height('100%')
132     }
133   }
134   ```
135