Shared Container
ArkTS Collections
ArkTS shared containers (@arkts.collections (ArkTS Collections)) are designed for high-performance data transmission between concurrent instances. They offer similar functionality to the containers defined in the ECMAScript 262 specification but with some key differences, which are outlined in Behavior Differences Between Shared Container APIs and Native APIs.
By default, ArkTS shared containers are passed by reference, allowing multiple concurrent instances to manipulate the same container instance. Pass-by-copy is also supported. In this mode, each concurrent instance holds an ArkTS container instance.
ArkTS shared containers are not thread-safe and employ a fail-fast mechanism to prevent concurrent structural modifications, which would otherwise trigger exceptions. When modifying container properties in a multithreaded scenario, you must use the asynchronous lock mechanism to ensure safe access.
The ArkTS shared containers include the following types: Array, Map, Set, TypedArray (Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Uint8ClampedArray and Float32Array), ArrayBuffer, BitVector, and ConcatArray. For details, see @arkts.collections (ArkTS Collections).
The following is an example of using the collection:
import { ArkTSUtils, collections, taskpool } from '@kit.ArkTS';
@Concurrent
async function add(arr: collections.Array<number>, lock: ArkTSUtils.locks.AsyncLock) {
await lock.lockAsync(() => { // Without the asynchronous lock, the task will fail due to data race conflicts.
arr[0]++;
})
}
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
RelativeContainer() {
Text(this.message)
.id('HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.onClick(() => {
let taskGroup = new taskpool.TaskGroup();
let lock = new ArkTSUtils.locks.AsyncLock();
let arr = collections.Array.create<number>(1, 0);
let count = 1000;
let num = count;
while (num--) {
taskGroup.addTask(add, arr, lock);
}
taskpool.execute(taskGroup).then(() => {
console.info(`Return success: ${arr[0]} === ${count}`);
}).catch((e: Error) => {
console.error("Return error.");
})
})
}
.height('100%')
.width('100%')
}
}
Behavior Differences Between Shared Container APIs and Native APIs
ArkTS provides shared containers for Sendable data, with some behavior differences when compared with native APIs. These differences are detailed below.
NOTE
ArkTS shared containers have different types from native ECMAScript 262 containers. Therefore, if the native isArray() method is used on a collections.Array instance object, false is returned.
ArkTS shared containers are passed by reference across threads, which is more efficient than native containers. If a large amount of data needs to be transferred across threads, you are advised to use ArkTS shared containers.
Array
You can convert a native array container to an ArkTS array container using the collections.Array.from method, or convert an ArkTS array container to a native array container using the native from method.
| Native API | ArkTS Collections API | Behavior Difference Exists | Different Behavior in ArkTS Collections |
|---|---|---|---|
| length: number | readonly length: number | Yes | To prevent the spread of undefined, it is not allowed to set length. |
| new(arrayLength ?: number): any[] | static create(arrayLength: number, initialValue: T): Array | Yes | To prevent the spread of undefined, a constructor must be provided with an initial value. |
| new <T>(arrayLength: number): T[] | constructor() | No | The data passed during construction must be of the Sendable type. Otherwise, a compilation error occurs. |
| new <T>(...items: T[]): T[] | constructor(first: T, ...left: T[]) | Yes | To prevent the spread of undefined, a constructor must be provided with an initial value. In inheritance scenarios, this constructor cannot be called to construct an object. |
| from<T>(arrayLike: ArrayLike<T>): T[] | static from<T>(arrayLike: ArrayLike<T>): Array<T> | No | / |
| from<T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[] | static from<U, T>(arrayLike: ArrayLike<U> | Iterable<U>, mapFn: ArrayFromMapFn<U, T>): Array<T> | No | / |
| pop(): T | undefined | pop(): T | undefined | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| push(...items: T[]): number | push(...items: T[]): number | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| concat(...items: ConcatArray<T>[]): T[] | concat(...items: ConcatArray<T>[]): Array<T> | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| concat(...items: (T | ConcatArray<T>)[]): T[] | concat(...items: ConcatArray<T>[]): Array<T> | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| join(separator?: string): string | join(separator?: string): string | No | / |
| shift(): T | undefined | shift(): T | undefined | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| slice(start?: number, end?: number): T[] | slice(start?: number, end?: number): Array<T> | No | / |
| sort(compareFn?: (a: T, b: T) => number): this | sort(compareFn?: (a: T, b: T) => number): Array<T> | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. In inheritance scenarios, the actual type of the return value cannot be obtained. |
| unshift(...items: T[]): number | unshift(...items: T[]): number | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| indexOf(searchElement: T, fromIndex?: number): number | indexOf(searchElement: T, fromIndex?: number): number | No | / |
| forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void | forEach(callbackFn: (value: T, index: number, array: Array<T>) => void): void | Yes | ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[] | map<U>(callbackFn: (value: T, index: number, array: Array<T>) => U): Array<U> | Yes | ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[] | filter(predicate: (value: T, index: number, array: Array<T>) => boolean): Array<T> | Yes | ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T | reduce(callbackFn: (previousValue: T, currentValue: T, currentIndex: number, array: Array<T>) => T): T | No | / |
| reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U | reduce<U>(callbackFn: (previousValue: U, currentValue: T, currentIndex: number, array: Array<T>) => U, initialValue: U): U | No | / |
| [n: number]: T | [index: number]: T | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| findIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number | findIndex(predicate: (value: T, index: number, obj: Array<T>) => boolean): number | Yes | ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| fill(value: T, start?: number, end?: number): this | fill(value: T, start?: number, end?: number): Array<T> | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. In inheritance scenarios, the actual type of the return value cannot be obtained. |
| entries(): IterableIterator<[number, T]> | entries(): IterableIterator<[number, T]> | No | / |
| keys(): IterableIterator<number> | keys(): IterableIterator<number> | No | / |
| values(): IterableIterator<T> | values(): IterableIterator<T> | No | / |
| includes(searchElement: T, fromIndex?: number): boolean | includes(searchElement: T, fromIndex?: number): boolean | No | / |
| at(index: number): T | undefined | at(index: number): T | undefined | No | / |
| isArray(arg: any): arg is any[] | static isArray(value: Object | undefined | null): boolean | Yes | Checks whether the array is an ArkTS array instance. If not, false is returned. |
| of<T>(...items: T[]): T[] | static of<T>(...items: T[]): Array<T> | No | / |
| copyWithin(target: number, start: number, end?: number): this | copyWithin(target: number, start: number, end?: number): Array<T> | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| lastIndexOf(searchElement: T, fromIndex?: number): number | lastIndexOf(searchElement: T, fromIndex?: number): number | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean | some(predicate: ArrayPredicateFn<T, Array<T>>): boolean | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T | reduceRight(callbackFn: ArrayReduceCallback<T, T, Array<T>>): T | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U | reduceRight<U = T>(callbackFn: ArrayReduceCallback<U, T, Array<T>>, initialValue: U): U | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| reverse(): T[] | reverse(): Array<T> | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| toString(): string | toString(): string | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| find(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined | find(predicate: (value: T, index: number, obj: Array<T>) => boolean): T | undefined | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| splice(start: number, deleteCount: number, ...items: T[]): T[] | splice(start: number, deleteCount: number, ...items: T[]): Array<T> | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean | every(predicate: ArrayPredicateFn<T, Array<T>>): boolean | Yes | ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| toLocaleString(): string | toLocaleString(): string | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
ArrayBuffer
| Native API | ArkTS Collections API | Behavior Difference Exists | Different Behavior in ArkTS Collections |
|---|---|---|---|
| readonly byteLength: number | readonly byteLength: number | No | / |
| slice(begin: number, end?: number): ArrayBuffer | slice(begin: number, end?: number): ArrayBuffer | No | / |
| new(byteLength: number): ArrayBuffer | constructor(byteLength: number) | No | / |
TypedArray (Int8Array Used as an Example)
You can convert a native Int8Array container into an ArkTS Int8Array container using the collections.Int8Array.from method, or convert an ArkTS Int8Array container into a native Int8Array container using the from method of the native Int8Array container.
| Native API | ArkTS Collections API | Behavior Difference Exists | Different Behavior in ArkTS Collections |
|---|---|---|---|
| readonly buffer: ArrayBufferLike | readonly buffer: ArrayBuffer | No | / |
| readonly byteLength: number | readonly byteLength: number | No | / |
| readonly byteOffset: number | readonly byteOffset: number | No | / |
| readonly length: number | readonly length: number | No | / |
| readonly BYTES_PER_ELEMENT: number | static readonly BYTES_PER_ELEMENT: number | No | / |
| copyWithin(target: number, start: number, end?: number): this | copyWithin(target: number, start: number, end?: number): Int8Array | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| every(predicate: (value: number, index: number, array: Int8Array) => unknown, thisArg?: any): boolean | every(predicate: TypedArrayPredicateFn<number, Int8Array>): boolean | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| fill(value: number, start?: number, end?: number): this | fill(value: number, start?: number, end?: number): Int8Array | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| filter(predicate: (value: number, index: number, array: Int8Array) => any, thisArg?: any): Int8Array | filter(predicate: TypedArrayPredicateFn<number, Int8Array>): Int8Array | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| find(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number | undefined | find(predicate: TypedArrayPredicateFn<number, Int8Array>): number | undefined | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| findIndex(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number | findIndex(predicate: TypedArrayPredicateFn<number, Int8Array>): number | Yes | ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| forEach(callbackfn: (value: number, index: number, array: Int8Array) => void, thisArg?: any): void | forEach(callbackFn: (value: number, index: number, array: Int8Array) => void): void | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| indexOf(searchElement: number, fromIndex?: number): number | indexOf(searchElement: number, fromIndex?: number): number | No | / |
| join(separator?: string): string | join(separator?: string): string | No | / |
| map(callbackfn: (value: number, index: number, array: Int8Array) => number, thisArg?: any): Int8Array | map(callbackFn: TypedArrayForEachCallback<number, Int8Array>): Int8Array | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number | reduce(callbackFn: TypedArrayReduceCallback<number, number, Int8Array>): number | No | / |
| reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number | reduce(callbackFn: TypedArrayReduceCallback<number, number, Int8Array>, initialValue: number): number | No | / |
| reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U | reduce<U>(callbackFn: TypedArrayReduceCallback<U, number, Int8Array>, initialValue: U): U | No | / |
| reverse(): Int8Array | reverse(): Int8Array | No | / |
| set(array: ArrayLike<number>, offset?: number): void | set(array: ArrayLike<number>, offset?: number): void | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| slice(start?: number, end?: number): Int8Array | slice(start?: number, end?: number): Int8Array | No | / |
| some(predicate: (value: number, index: number, array: Int8Array) => unknown, thisArg?: any): boolean | some(predicate: TypedArrayPredicateFn<number, Int8Array>): boolean | Yes | ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| sort(compareFn?: (a: number, b: number) => number): this | sort(compareFn?: TypedArrayCompareFn<number>): Int8Array | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. In inheritance scenarios, the actual type of the return value cannot be obtained. |
| subarray(begin?: number, end?: number): Int8Array | subarray(begin?: number, end?: number): Int8Array | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| [index: number]: number | [index: number]: number | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| entries(): IterableIterator<[number, number]> | entries(): IterableIterator<[number, number]> | No | / |
| keys(): IterableIterator<number> | keys(): IterableIterator<number> | No | / |
| values(): IterableIterator<number> | values(): IterableIterator<number> | No | / |
| includes(searchElement: number, fromIndex?: number): boolean | includes(searchElement: number, fromIndex?: number): boolean | No | / |
| at(index: number): number | undefined | at(index: number): number | undefined | No | / |
| new(length: number): Int8Array | constructor(length: number) | No | / |
| new(array: ArrayLike<number> | ArrayBufferLike): Int8Array | constructor(array: ArrayLike<number> | ArrayBuffer) | No | / |
| new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int8Array | constructor(buffer: ArrayBuffer, byteOffset?: number, length?: number) | No | / |
| from(arrayLike: ArrayLike<number>): Int8Array | static from(arrayLike: ArrayLike<number>): Int8Array | No | / |
| from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Int8Array | static from<T>(arrayLike: ArrayLike<T>, mapFn: TypedArrayFromMapFn<T, number>): Int8Array | Yes | ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Int8Array | static from(arrayLike: Iterable<number>, mapFn?: TypedArrayFromMapFn<number, number>): Int8Array | Yes | ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| of(...items: number[]): Int8Array | static of(...items: number[]): Int8Array | No | / |
| toString(): string | toString(): string | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| toLocaleString(): string | toLocaleString(): string | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| lastIndexOf(searchElement: number, fromIndex?: number): number | lastIndexOf(searchElement: number, fromIndex?: number): number | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number | reduceRight(callbackFn: TypedArrayReduceCallback<number, number, Int8Array>): number | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U | reduceRight<U = number>(callbackFn: TypedArrayReduceCallback<U, number, Int8Array>, initialValue: U): U | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
Map
| Native API | ArkTS Collections API | Behavior Difference Exists | Different Behavior in ArkTS Collections |
|---|---|---|---|
| readonly size: number | readonly size: number | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| clear(): void | clear(): void | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| delete(key: K): boolean | delete(key: K): boolean | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void | forEach(callbackFn: (value: V, key: K, map: Map<K, V>) => void): void | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| get(key: K): V | undefined | get(key: K): V | undefined | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| has(key: K): boolean | has(key: K): boolean | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| set(key: K, value: V): this | set(key: K, value: V): Map<K, V> | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| entries(): IterableIterator<[K, V]> | entries(): IterableIterator<[K, V]> | No | / |
| keys(): IterableIterator<K> | keys(): IterableIterator<K> | No | / |
| values(): IterableIterator<V> | values(): IterableIterator<V> | No | / |
| new <K, V>(entries?: readonly (readonly [K, V])[] | null): Map<K, V> | constructor(entries?: readonly (readonly [K, V])[] | null) | Yes | The passed-in values of k and v during construction cannot be non-Sendable data. Otherwise, an error is reported during compilation. |
Set
| Native API | ArkTS Collections API | Behavior Difference Exists | Different Behavior in ArkTS Collections |
|---|---|---|---|
| readonly size: number | readonly size: number | Yes | Computed property names (arkts-sendable-compated-prop-name) cannot be used in Sendable classes and interfaces. |
| add(value: T): this | add(value: T): Set<T> | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| clear(): void | clear(): void | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| delete(value: T): boolean | delete(value: T): boolean | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void | forEach(callbackFn: (value: T, value2: T, set: Set<T>) => void): void | Yes | 1. It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. 2. ArkTS does not support this. As a result, the thisArg parameter is not supported. |
| has(value: T): boolean | has(value: T): boolean | Yes | It is not allowed to add, delete, or modify elements during iteration or access. Otherwise, an exception is thrown. |
| entries(): IterableIterator<[T, T]> | entries(): IterableIterator<[T, T]> | No | / |
| keys(): IterableIterator<T> | keys(): IterableIterator<T> | No | / |
| values(): IterableIterator<T> | values(): IterableIterator<T> | Yes | Computed property names (arkts-sendable-compated-prop-name) cannot be used in Sendable classes and interfaces. |
| new <T = any>(values?: readonly T[] | null): Set<T> | constructor(values?: readonly T[] | null) | Yes | The data passed during construction must be of the Sendable type. Otherwise, a compilation error occurs. |