taskpool 传递参数;
在调用方法时传递多个值;代码如下:
@Concurrent
function culSum(param1:number,param2:number){
let sum = param1+param2
console.log(`--------- > taskpool ${sum} .. param1 ${param1} .. params2 ${param2}` )
return sum;
}
taskpool.execute(culSum, 10, 10).catch(() => {
})
.then((result) => {
console.log('--------- > taskpool result ' + result)
})
执行结果代码:
--------- > taskpool 20 .. param1 10 .. params2 10
--------- > taskpool result 20
其实在taskpool.execute()方法针对参数的传递是不限制个数的;相应的参数代码如下:
function execute(func: Function, ...args: Object[]): Promise<Object>;
args:参数有点类似于kotlin 方法中的 vararg,java 中的 String... ;
如何在@Concurrent 方法中调用其他方法:
在@Concurrent 方法中调用其他方法;在平时的开发中,如果在子线程执行任务,不可能就写一个方法直接将全部的业务都堆积到内部。因此我们可能根据设计模式的单一原则,将功能进行拆分成多个方法执行;但是在鸿蒙中@Concurrent 方法 是禁止使用闭包变量。
例如错误代码
function bar() {
}
@Concurrent
function foo() {
bar(); // 违反闭包原则,报错
}
那么在开发中,可以通过在调用方法时传递进入一个共享对象,在该对象类中存在执行的逻辑;或者直接使用工具类调用其静态方法;代码如下:
model:
@Sendable
export class StudentModel{
public name:string = '小明'
constructor( name: string) {
this.name = name
}
//执行的方法,在子线程中
culSum(param:number,param2:number){
return param +param2
}
}
触发代码:
let student = new StudentModel( '小明')
taskpool.execute(verifyEnum, student).catch(() => {
}).then((result) => {
console.error('--------- > taskpool '+JSON.stringify(result))
})
方法:
@Concurrent
function verifyEnum(student: StudentModel) {
console.error('--------- > taskpool ' + JSON.stringify(student))
student.name = '小花'
student.culSum(10,10)
return student
}
同样也可以调用静态方法执行相关逻辑 如下:
export class StudentUtil {
private constructor() {
}
static culSum(param: number, param2: number) {
return param + param2
}
}
方法:
@Concurrent
function verifyEnum(student: StudentModel) {
let sum = student.culSum(10,10)
let sum1 = StudentUtil.culSum(11,11)
console.error(`--------- > taskpool sum ${sum} sum1 ${sum1}`)
return student
}
结果:
--------- > taskpool sum 20 sum1 22
遇见问题:
1.在使用taskpool 过程中,如果在接收方法上添加了 async 后,需要在taskpool.execute 方法添加await 否则也无法正常的拿到值;
2.在低版本中在自定义 bean类上添加了@Sendable 后,无法使用枚举类型;这个升级版本就可以了;
3.线程间数据传递,如果自定义 Bean 不添加@Sendable 是采用的序列化方式;因此在子线程中的对象调用对象类中的方法会失效;
疑问:
疑问:1.在传递 array 数据进入子线程时,出现了 hashcode 相同,但是在值没有改变问题;
在没有使用@Sendable的情况下,传递数组是深拷贝(系统会自动执行序列化/反序列化(深拷贝),两个数组互不影响。深拷贝或缺乏同步机制导致。
疑问:在设置@sendable 和在外部添加 used shared 区别
“use shared”:共享模块是进程内只会加载一次的模块,使用"use shared"这一指令来标记一个模块是否为共享模块。主要应用于在线程中仅仅创建一次的实例;也就是单例。避免在进程中出现多个对象;
@Sendable:目的是让传递的序列化 更改成传递引用对象;@Sendable 仅标记对象可跨线程传递引用(避免序列化),同时能够实现子线程更改对象的值,子线程也会更改。因此出现读写操作时需要添加锁(ArkTSUtils.locks.AsyncLock);
疑问:如果子线程执行完成,会释放资源吗?
子线程的方法调用完成后会释放相应的传递集合以及对象的资源,但是子线程可能并不会立即销毁;
子线程传递选集合时如何抉择;
由于在将项目中的数据传递到子线程时,会存在选择传递Array[],还是转换为 colletions.Array 的疑惑;同时两者转换也比较耗时;因此要区分来更好的的选择;
针对在线程间传递集合时,传递collections.array 和传递 array 的区别:
1.传递collections.array 可以在子线程更改数据的时候,主线程也会更改,同时不会进行深拷贝,也就是不会在子线程再次开辟一份内存空间,
如果设置主线程和子线程都更改数组的值;那么就需要添加锁,来保证数据的安全性;
2.使用 array 会涉及到深拷贝,占用内存空间,在子线程更改数据,主线程不会更改;不用考虑数据存在多线程并发问题;
进行针对性如何选择:
1.如果数据不涉及线程间大数据量的频繁交互,以及数据实时同步问题,高频读写的大数据集;就考虑 array,反之使用 collection.Array
如果描述中出现问题,请各位大佬不吝赐教;