1# 共享模块 2 3共享模块是进程内只会加载一次的模块,使用"use shared"这一指令来标记一个模块是否为共享模块。 4 5非共享模块在同一线程内只加载一次,在不同线程间会加载多次,在不同的线程内都会产生新的模块对象。因此可以使用共享模块来实现进程单例。 6 7 8## 约束限制 9 10- "use shared"需要与"use strict"一样写在ArkTS文件顶层,写在import语句之后其他语句之前。 11 12 共享属性不存在传递性,即非共享模块A不会引入了共享模块B而使A变成共享。 13 14 15- 共享模块只支持ets文件。 16 17- 共享模块内不允许使用side-effects-import。 18 19 共享模块在同一进程内只加载一次,可在不同线程间共享。<br/> 20 共享模块加载时,导入的非共享模块不会立刻加载。在共享模块内访问依赖的非共享模块导出变量时,会在本线程懒加载对应的非共享模块,非共享模块在线程间是隔离的,不同线程访问时都会进行至多一次的模块懒加载。<br/> 21 由于side-effects-import不涉及导出变量,所以永远不会被加载,因此不支持。 22 23 ```ts 24 // 不允许使用side-effects-import 25 import "./sharedModule" 26 ``` 27 28- 共享模块导出的变量必须都是可共享对象。 29 30 共享模块在并发实例间可共享,因此模块导出的所有对象都必须是可共享的,可共享对象参考[Sendable规格](sendable-constraints.md)。 31 32- 共享模块中不允许直接导出模块。 33 34 ```ts 35 // test.ets 36 export let num = 1; 37 export let str = 'aaa'; 38 39 // 共享模块 40 'use shared' 41 42 export * from './test'; // 编译报错,不允许直接导出模块 43 export {num, str} from './test'; // 正确示例,导出对象合集 44 ``` 45 46 47- 共享模块可以引用共享模块或非共享模块。不限制共享模块的引用和被引用场景。 48 49- napi_load_module、napi_load_module_with_info以及动态加载不支持加载共享模块。 50 51 52## 使用示例 53 541. 共享模块内导出Sendable对象。 55 56 ```ts 57 // 共享模块sharedModule.ets 58 import { ArkTSUtils } from '@kit.ArkTS'; 59 60 // 声明当前模块为共享模块,只能导出可Sendable数据 61 "use shared" 62 63 // 共享模块,SingletonA全局唯一 64 @Sendable 65 class SingletonA { 66 private count_: number = 0; 67 lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock() 68 69 public async getCount(): Promise<number> { 70 return this.lock_.lockAsync(() => { 71 return this.count_; 72 }) 73 } 74 75 public async increaseCount() { 76 await this.lock_.lockAsync(() => { 77 this.count_++; 78 }) 79 } 80 } 81 82 export let singletonA = new SingletonA(); 83 ``` 84 852. 在多个线程中操作共享模块导出的对象。 86 87 ```ts 88 import { taskpool } from '@kit.ArkTS'; 89 import { singletonA } from './sharedModule'; 90 91 @Concurrent 92 async function increaseCount() { 93 await singletonA.increaseCount(); 94 console.info("SharedModule: count is:" + await singletonA.getCount()); 95 } 96 97 @Concurrent 98 async function printCount() { 99 console.info("SharedModule: count is:" + await singletonA.getCount()); 100 } 101 102 @Entry 103 @Component 104 struct Index { 105 @State message: string = 'Hello World'; 106 107 build() { 108 Row() { 109 Column() { 110 Button("MainThread print count") 111 .onClick(async () => { 112 await printCount(); 113 }) 114 Button("Taskpool print count") 115 .onClick(async () => { 116 await taskpool.execute(printCount); 117 }) 118 Button("MainThread increase count") 119 .onClick(async () => { 120 await increaseCount(); 121 }) 122 Button("Taskpool increase count") 123 .onClick(async () => { 124 await taskpool.execute(increaseCount); 125 }) 126 } 127 .width('100%') 128 } 129 .height('100%') 130 } 131 } 132 ``` 133