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** and **napi_load_module_with_info** support loading of shared modules. 52 53- Dynamic loading does not support loading of shared modules. 54 55## Usage Example 56 571. Export a Sendable object from a shared module. 58 59 ```ts 60 // Shared module sharedModule.ets 61 import { ArkTSUtils } from '@kit.ArkTS'; 62 63 // Declare the current module as shared. Only Sendable data can be exported. 64 "use shared" 65 66 // Shared module. SingletonA is globally unique. 67 @Sendable 68 class SingletonA { 69 private count_: number = 0; 70 lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock() 71 72 public async getCount(): Promise<number> { 73 return this.lock_.lockAsync(() => { 74 return this.count_; 75 }) 76 } 77 78 public async increaseCount() { 79 await this.lock_.lockAsync(() => { 80 this.count_++; 81 }) 82 } 83 } 84 85 export let singletonA = new SingletonA(); 86 ``` 87 882. Operate an object exported from the shared module across multiple threads. 89 90 ```ts 91 import { taskpool } from '@kit.ArkTS'; 92 import { singletonA } from './sharedModule'; 93 94 @Concurrent 95 async function increaseCount() { 96 await singletonA.increaseCount(); 97 console.info("SharedModule: count is:" + await singletonA.getCount()); 98 } 99 100 @Concurrent 101 async function printCount() { 102 console.info("SharedModule: count is:" + await singletonA.getCount()); 103 } 104 105 @Entry 106 @Component 107 struct Index { 108 @State message: string = 'Hello World'; 109 110 build() { 111 Row() { 112 Column() { 113 Button("MainThread print count") 114 .onClick(async () => { 115 await printCount(); 116 }) 117 Button("Taskpool print count") 118 .onClick(async () => { 119 await taskpool.execute(printCount); 120 }) 121 Button("MainThread increase count") 122 .onClick(async () => { 123 await increaseCount(); 124 }) 125 Button("Taskpool increase count") 126 .onClick(async () => { 127 await taskpool.execute(increaseCount); 128 }) 129 } 130 .width('100%') 131 } 132 .height('100%') 133 } 134 } 135 ``` 136