1# Concurrent Loading of Service Modules 2 3During application launch, multiple service modules need to be loaded. For example, in a mapping application, different modules such as positioning, ride-hailing, and navigation are required. Initializing all these modules in the UI main thread can significantly increase the cold start time of the application. To address this, these modules should be loaded concurrently in separate child threads to reduce launch latency. 4 5By leveraging the TaskPool capabilities provided by ArkTS, different service initialization tasks can be offloaded to child threads. Service modules can be implemented in C++ as [NativeBinding objects](transferabled-object.md) or defined in ArkTS as [Sendable objects](arkts-sendable.md). The initialized modules can then be returned to the UI main thread for use. The implementation involves the following steps: 6 71. Define each service module (SDK) (using Sendable objects as an example). 8 9 Define the calculator service module as follows: 10 11 ```ts 12 // sdk/Calculator.ets 13 import { collections } from '@kit.ArkTS' 14 15 @Sendable 16 export class Calculator { 17 history?: collections.Array<collections.Array<string>> 18 totalCount: number = 0 19 20 static init(): Calculator { 21 let calc = new Calculator() 22 calc.totalCount = 0 23 calc.history = collections.Array.create(calc.totalCount, collections.Array.create(2, "")); 24 return calc 25 } 26 27 add(a: number, b: number) { 28 let result = a + b; 29 this.newCalc(`${a} + ${b}`, `${result}`); 30 return result 31 } 32 33 sub(a: number, b: number) { 34 let result = a - b; 35 this.newCalc(`${a} - ${b}`, `${result}`); 36 return result 37 } 38 39 mul(a: number, b: number) { 40 let result = a * b; 41 this.newCalc(`${a} * ${b}`, `${result}`); 42 return result 43 } 44 45 div(a: number, b: number) { 46 let result = a / b; 47 this.newCalc(`${a} / ${b}`, `${result}`); 48 return result 49 } 50 51 getHistory(): collections.Array<collections.Array<string>> { 52 return this.history!; 53 } 54 55 showHistory() { 56 for (let i = 0; i < this.totalCount; i++) { 57 console.info(`${i}: ${this.history![i][0]} = ${this.history![i][1]}`) 58 } 59 } 60 61 private newCalc(opt: string, ret: string) { 62 let newRecord = new collections.Array<string>(opt, ret) 63 this.totalCount = this.history!.unshift(newRecord) 64 } 65 } 66 ``` 67 <!-- @[define_calculator_module](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ApplicationMultithreadingDevelopment/PracticalCases/entry/src/main/ets/sdk/Calculator.ets) --> 68 69 Define the timer service module as follows: 70 71 ```ts 72 // sdk/TimerSdk.ets 73 @Sendable 74 export class TimerSdk { 75 static init(): TimerSdk { 76 let timer = new TimerSdk() 77 return timer 78 } 79 80 async Countdown(time: number) { 81 return new Promise((resolve: (value: boolean) => void) => { 82 setTimeout(() => { 83 resolve(true) 84 }, time) 85 }) 86 } 87 } 88 ``` 89 <!-- @[define_timer_module](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ApplicationMultithreadingDevelopment/PracticalCases/entry/src/main/ets/sdk/TimerSdk.ets) --> 90 912. In the UI main thread, trigger the distribution of service modules to child threads, and use them in the UI main thread after loading is complete. The following is an example: 92 93 ```ts 94 // Index.ets 95 import { Calculator } from '../sdk/Calculator' 96 import { TimerSdk } from '../sdk/TimerSdk' 97 import { taskpool } from '@kit.ArkTS'; 98 99 @Concurrent 100 function initCalculator(): Calculator { 101 return Calculator.init() 102 } 103 104 @Concurrent 105 function initTimerSdk(): TimerSdk { 106 return TimerSdk.init() 107 } 108 109 @Entry 110 @Component 111 struct Index { 112 calc?: Calculator 113 timer?: TimerSdk 114 115 aboutToAppear(): void { 116 taskpool.execute(initCalculator).then((ret) => { 117 this.calc = ret as Calculator 118 }) 119 taskpool.execute(initTimerSdk).then((ret) => { 120 this.timer = ret as TimerSdk 121 }) 122 } 123 124 build() { 125 Row() { 126 Column() { 127 Text("calculate add") 128 .id('add') 129 .fontSize(50) 130 .fontWeight(FontWeight.Bold) 131 .alignRules({ 132 center: { anchor: '__container__', align: VerticalAlign.Center }, 133 middle: { anchor: '__container__', align: HorizontalAlign.Center } 134 }) 135 .onClick(async () => { 136 let result = this.calc?.add(1, 2) 137 console.info(`Result is ${result}`) 138 }) 139 Text("show history") 140 .id('show') 141 .fontSize(50) 142 .fontWeight(FontWeight.Bold) 143 .alignRules({ 144 center: { anchor: '__container__', align: VerticalAlign.Center }, 145 middle: { anchor: '__container__', align: HorizontalAlign.Center } 146 }) 147 .onClick(async () => { 148 this.calc?.showHistory() 149 }) 150 Text("countdown") 151 .id('get') 152 .fontSize(50) 153 .fontWeight(FontWeight.Bold) 154 .alignRules({ 155 center: { anchor: '__container__', align: VerticalAlign.Center }, 156 middle: { anchor: '__container__', align: HorizontalAlign.Center } 157 }) 158 .onClick(async () => { 159 console.info(`Timer start`) 160 await this.timer?.Countdown(1000); 161 console.info(`Timer end`) 162 }) 163 } 164 .width('100%') 165 } 166 .height('100%') 167 } 168 } 169 ``` 170 <!-- @[distribute_child_thread](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ApplicationMultithreadingDevelopment/PracticalCases/entry/src/main/ets/managers/ConcurrentLoadingModulesGuide.ets) --> 171