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