首先明確一點ArkTS是單線程模型,底層線程模型對接了libuv。在應(yīng)用進程啟動后,會有多個I/O線程用于I/O操作。JS線程的I/O異步操作,會在I/O線程執(zhí)行,JS線程可以同時執(zhí)行其他操作,不存在阻塞等待問題。
多線程數(shù)據(jù)共享
大部分普通對象跨線程均采用序列化方式,線程間對象的數(shù)據(jù)通信依賴序列化、反序列化,耗時與數(shù)據(jù)量相關(guān),需要控制傳輸?shù)臄?shù)據(jù)量。也可采用通過ArrayBuffer的轉(zhuǎn)移傳輸和SharedArrayBuffer進行共享。-
大量線程并發(fā)方案
當(dāng)前ArkTS提供了TaskPool和Worker兩種并發(fā)能力,TaskPool和Worker都基于Actor并發(fā)模型實現(xiàn)。大量線程并發(fā)時- 將多線程任務(wù)轉(zhuǎn)變?yōu)椴l(fā)任務(wù),通過TaskPool分發(fā)執(zhí)行。
- I/O型任務(wù)不需要單獨開啟線程,而是在當(dāng)前線程(可以是TaskPool線程)執(zhí)行。
- 少量需要常駐的CPU密集型任務(wù),采用Worker,并且需要控制在64個及以下。
-
TaskPool和Worker
不同點:兩者是不同顆粒度的并發(fā)API,Worker更像Thread或者Service維度,Task就是單一任務(wù)維度。同時TaskPool簡化開發(fā)者開發(fā)并發(fā)程序,支持優(yōu)先級和取消,并且通過統(tǒng)一管理節(jié)省系統(tǒng)資源優(yōu)化調(diào)度。
相同點:在JS相關(guān)的線程間交互上,二者本質(zhì)都是內(nèi)存隔離模型,參數(shù)與范圍值的限制是一致的,也有開銷。
調(diào)度機制:
TaskPool與Worker采用事件循環(huán)接收線程間通信的消息。數(shù)量、優(yōu)先級
TaskPool內(nèi)部會動態(tài)調(diào)整線程個數(shù),不支持設(shè)置數(shù)量,只需要往線程池中拋任務(wù),確保高優(yōu)先級任務(wù)的及時執(zhí)行。
Worker的線程個數(shù)最多64個,如果Worker超過規(guī)定個數(shù),會創(chuàng)建失敗。
TaskPool與Worker兩者獨立,不相互影響,因此Worker在達到上限數(shù)量時,不會影響TaskPool線程安全
ArkTS的多線程是基于事件共享實現(xiàn)的,其數(shù)據(jù)交換是基于事件進行傳遞對象,所以不存在線程安全的問題。
ArkTS語言基礎(chǔ)類庫提供的taskPool和worker兩個多線程的方案,都是基于Actor并發(fā)模型實現(xiàn)的。Actor并發(fā)模型是基于事件基礎(chǔ)傳遞數(shù)據(jù),不需要開發(fā)者去面對鎖帶來的一系列復(fù)雜偶發(fā)的問題,是線程安全的,同時并發(fā)度也相對較高。目前線程間的數(shù)據(jù)傳輸支持的對象分為三類,普通的JavaScript對象,可轉(zhuǎn)移對象,可共享對象。