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