1# Shared Module Development 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## Specifications 8 9A shared module complies with the following restrictions: 10 11- Similar to **use strict**, **use shared** must be written at the top of the file after the **import** statement but before other statements. 12 13 The shared attribute cannot be passed on. That is, importing a shared module does not make a non-shared module shared. 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 // Not allowed 23 import "./sharedModule" 24 ``` 25 26- Variables exported by a shared module must be sendable objects. 27 28 Objects exported by a shared module must be sendable. For details about the sendable objects, see [Sendable Development](arkts-sendable.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- A shared module can reference a shared module or a non-shared module. 45 46 The reference and reference scenarios of shared modules are not restricted. 47 48## Example 49 501. Export the sendable object in a shared module. 51 52 ```ts 53 // Shared module sharedModule.ets 54 import { ArkTSUtils } from '@kit.ArkTS'; 55 56 // Declare the current module as a shared module. Only sendable data can be exported. 57 "use shared" 58 59 // Shared module. SingletonA is globally unique. 60 @Sendable 61 export class SingletonA { 62 private count_: number = 0; 63 lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock(); 64 private static instance: SingletonA = new SingletonA(); 65 static getInstance(): SingletonA { 66 // Return a singleton object. 67 return SingletonA.instance; 68 } 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 842. Operate the object exported from the shared module in multiple threads. 85 86 ```ts 87 import { ArkTSUtils, taskpool } from '@kit.ArkTS'; 88 import { SingletonA } from './sharedModule' 89 90 @Concurrent 91 async function increaseCount() { 92 await SingletonA.getInstance().increaseCount(); 93 console.info("SharedModule: count is:" + await SingletonA.getInstance().getCount()); 94 } 95 96 @Concurrent 97 async function printCount() { 98 console.info("SharedModule: count is:" + await SingletonA.getInstance().getCount()); 99 } 100 101 @Entry 102 @Component 103 struct Index { 104 @State message: string = 'Hello World'; 105 106 build() { 107 Row() { 108 Column() { 109 Button("MainThread print count") 110 .onClick(async () => { 111 console.info("this is MainThread print count"); 112 await printCount(); 113 }) 114 Button("Taskpool print count") 115 .onClick(async () => { 116 console.info("this is Taskpool print count"); 117 await taskpool.execute(printCount); 118 }) 119 Button("MainThread increase count") 120 .onClick(async () => { 121 console.info("this is MainThread increase count"); 122 await increaseCount(); 123 }) 124 Button("Taskpool increase count") 125 .onClick(async () => { 126 console.info("this is Taskpool increase count"); 127 await taskpool.execute(increaseCount); 128 }) 129 } 130 .width('100%') 131 } 132 .height('100%') 133 } 134 } 135 ``` 136