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 only once in the same thread and multiple times in different threads. New module objects are generated in all these threads. Therefore, a shared module can be used to implement a singleton of a process. 6 7 8## Constraints 9 10- Similar to **use strict**, **use shared** must be written at the top of the file after the **import** statement but before other statements. 11 12 The shared attribute cannot be passed on. That is, importing a shared module does not make a non-shared module shared. 13 14 15- A shared module supports only .ets files. 16 17- **side-effects-import** is not allowed within a shared module. 18 19 After a module is shared between threads, functions are lazy loaded to dependent non-shared modules. This type of import does not involve variable export and therefore is not loaded. 20 21 ```ts 22 // side-effects-import is not allowed. 23 import "./sharedModule" 24 ``` 25 26- Variables exported by a shared module must be sendable objects. 27 28 Shared modules can be shared among concurrent instances. Therefore, all objects exported by a module must be shareable. For details about shareable objects, see [Sendable Usage Rules and Constraints](sendable-constraints.md). 29 30- Modules cannot be directly exported from a shared module. 31 32 ```ts 33 // test.ets 34 export let num = 1; 35 export let str = 'aaa'; 36 37 // Shared module 38 'use shared' 39 40 export * from './test'; // A compile-time error is reported. The module cannot be directly exported. 41 export {num, str} from './test'; // Correct example. Export the object set. 42 ``` 43 44 45- A shared module can reference a shared module or a non-shared module. The reference and reference scenarios of shared modules are not restricted. 46 47- napi_load_module, napi_load_module_with_info, and dynamic loading do not support the loading of shared modules. 48 49 50## Example 51 521. Export the sendable object in a shared module. 53 54 ```ts 55 // Shared module sharedModule.ets 56 import { ArkTSUtils } from '@kit.ArkTS'; 57 58 // Declare the current module as a shared module. Only sendable data can be exported. 59 "use shared" 60 61 // Shared module. SingletonA is globally unique. 62 @Sendable 63 class SingletonA { 64 private count_: number = 0; 65 lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock() 66 67 public async getCount(): Promise<number> { 68 return this.lock_.lockAsync(() => { 69 return this.count_; 70 }) 71 } 72 73 public async increaseCount() { 74 await this.lock_.lockAsync(() => { 75 this.count_++; 76 }) 77 } 78 } 79 80 export let singletonA = new SingletonA(); 81 ``` 82 832. Operate the object exported from the shared module in multiple threads. 84 85 ```ts 86 import { ArkTSUtils, taskpool } from '@kit.ArkTS'; 87 import { singletonA } from './sharedModule'; 88 89 @Sendable 90 export class A { 91 private count_: number = 0; 92 lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock(); 93 94 public async getCount(): Promise<number> { 95 return this.lock_.lockAsync(() => { 96 return this.count_; 97 }) 98 } 99 100 public async increaseCount() { 101 await this.lock_.lockAsync(() => { 102 this.count_++; 103 }) 104 } 105 } 106 107 @Concurrent 108 async function increaseCount() { 109 await singletonA.increaseCount(); 110 console.info("SharedModule: count is:" + await singletonA.getCount()); 111 } 112 113 @Concurrent 114 async function printCount() { 115 console.info("SharedModule: count is:" + await singletonA.getCount()); 116 } 117 118 @Entry 119 @Component 120 struct Index { 121 @State message: string = 'Hello World'; 122 123 build() { 124 Row() { 125 Column() { 126 Button("MainThread print count") 127 .onClick(async () => { 128 await printCount(); 129 }) 130 Button("Taskpool print count") 131 .onClick(async () => { 132 await taskpool.execute(printCount); 133 }) 134 Button("MainThread increase count") 135 .onClick(async () => { 136 await increaseCount(); 137 }) 138 Button("Taskpool increase count") 139 .onClick(async () => { 140 await taskpool.execute(increaseCount); 141 }) 142 } 143 .width('100%') 144 } 145 .height('100%') 146 } 147 } 148 ``` 149