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