首先明确一点ArkTS是单线程模型,底层线程模型对接了libuv。在应用进程启动后,会有多个I/O线程用于I/O操作。JS线程的I/O异步操作,会在I/O线程执行,JS线程可以同时执行其他操作,不存在阻塞等待问题。
多线程数据共享
大部分普通对象跨线程均采用序列化方式,线程间对象的数据通信依赖序列化、反序列化,耗时与数据量相关,需要控制传输的数据量。也可采用通过ArrayBuffer的转移传输和SharedArrayBuffer进行共享。-
大量线程并发方案
当前ArkTS提供了TaskPool和Worker两种并发能力,TaskPool和Worker都基于Actor并发模型实现。大量线程并发时- 将多线程任务转变为并发任务,通过TaskPool分发执行。
- I/O型任务不需要单独开启线程,而是在当前线程(可以是TaskPool线程)执行。
- 少量需要常驻的CPU密集型任务,采用Worker,并且需要控制在64个及以下。
-
TaskPool和Worker
不同点:两者是不同颗粒度的并发API,Worker更像Thread或者Service维度,Task就是单一任务维度。同时TaskPool简化开发者开发并发程序,支持优先级和取消,并且通过统一管理节省系统资源优化调度。
相同点:在JS相关的线程间交互上,二者本质都是内存隔离模型,参数与范围值的限制是一致的,也有开销。
调度机制:
TaskPool与Worker采用事件循环接收线程间通信的消息。数量、优先级
TaskPool内部会动态调整线程个数,不支持设置数量,只需要往线程池中抛任务,确保高优先级任务的及时执行。
Worker的线程个数最多64个,如果Worker超过规定个数,会创建失败。
TaskPool与Worker两者独立,不相互影响,因此Worker在达到上限数量时,不会影响TaskPool线程安全
ArkTS的多线程是基于事件共享实现的,其数据交换是基于事件进行传递对象,所以不存在线程安全的问题。
ArkTS语言基础类库提供的taskPool和worker两个多线程的方案,都是基于Actor并发模型实现的。Actor并发模型是基于事件基础传递数据,不需要开发者去面对锁带来的一系列复杂偶发的问题,是线程安全的,同时并发度也相对较高。目前线程间的数据传输支持的对象分为三类,普通的JavaScript对象,可转移对象,可共享对象。