1# CommonLibrary子系统变更说明 2 3## cl.commonlibrary.1 taskpool传输Sendable数据行为变更 4 5**访问级别** 6 7其他 8 9**变更原因** 10 11taskpool执行并发任务,对于Sendable数据类型,以执行结果返回或sendData接口传输时,将Sendable数据的传输方式由克隆转为共享。考虑到taskpool任务执行后的数据再次使用的场景几乎不存在,从设计上也不推荐,因此从taskpool接口的易用性考虑,对默认的传输行为进行变更。 12 13**变更影响** 14 15此变更为非兼容变更 16变更前,使用API11的taskpool.Task.sendData接口发送或直接返回Sendable数据时,会默认拷贝一份。 17变更后,在该场景下,Sendable数据会共享传输,此时如果在主线程修改,子线程也会感知到变化。但是由于taskpool以任务维度执行,对一个对象的同时操作场景较少,后续的数据变化对taskpool的影响可控。 18如下代码,打印出来的值可能是100,也可能被子线程改成200: 19``` 20import { taskpool } from '@kit.ArkTS' 21@Sendable 22class A { 23 num: number = 100 24} 25@Concurrent 26async function foo(a: A) { 27 taskpool.Task.sendData(a) 28 a.num = 200 29} 30let a: A = new A() 31let task = new taskpool.Task(foo, a) 32task.onReceiveData((val: A) => { 33 console.log("num: " + val.num) 34}) 35``` 36 37**起始 API Level** 38 39Sendable接口从API 11起启用。 40 41**变更发生版本** 42 43从OpenHarmony SDK 5.0.0.18 开始。 44 45**变更的接口/组件** 46 47不涉及。 48 49**适配指导** 50 51如果不涉及taskpool执行sendData或者返回数据后仍然在两个线程分别读写同一个属性,则不需要适配。 52如果taskpool执行sendData或者返回数据后,如果宿主线程与子线程分别读写同一个属性,需要使用锁进行保护(从@arkts.utils导入)。 53当前代码: 54``` 55import { taskpool } from '@kit.ArkTS' 56@Sendable 57class A { 58 num: number = 100 59} 60@Concurrent 61async function foo(a: A) { 62 taskpool.Task.sendData(a) 63 a.num = 200 64} 65let a: A = new A() 66let task = new taskpool.Task(foo, a) 67task.onReceiveData((val: A) => { 68 console.log("num: " + val.num) 69}) 70``` 71为了保证class A的num域线程安全,需要增加同步保护,推荐改法: 72``` 73import { taskpool } from '@kit.ArkTS' 74@Sendable 75class A { 76 num: number = 100 77 async setNum(num: number) { 78 // add lock here 79 this.num = num 80 } 81 async getNum(): Promise<number> { 82 // add lock here 83 return this.num 84 } 85} 86@Concurrent 87async function foo(a: A) { 88 taskpool.Task.sendData(a) 89 a.setNum(200) 90} 91let a: A = new A() 92let task = new taskpool.Task(foo, a) 93task.onReceiveData((val: A) => { 94 console.log("num: " + val.getNum()) 95}) 96``` 97