Що таке SharedArrayBuffer?
Визначення
SharedArrayBuffer- це спеціальний тип об'єкта в JavaScript, який надає спільну область пам'яті, доступну одночасно кільком потокам (наприклад,worker_threadsу Node.js).
Ідея
Звичайні об'єкти й масиви під час передачі між потоками копіюються.
SharedArrayBuffer дозволяє:
- розділяти ту саму ділянку пам'яті між потоками,
- уникати копіювання великих даних,
- синхронізувати доступ через атомарні операції (
Atomics).
Простіше кажучи:
Це як "спільна RAM-ділянка", яку можуть читати й змінювати всі потоки всередині одного процесу Node.js.
1. Приклад використання
main.js
const { Worker } = require('worker_threads');
// Створюємо спільний буфер на 4 байти * 10 елементів
const shared = new SharedArrayBuffer(4 * 10);
const sharedArray = new Int32Array(shared);
sharedArray[0] = 10;
sharedArray[1] = 20;
const worker = new Worker('./worker.js', { workerData: shared });
worker.on('exit', () => {
console.log('Головний потік бачить:', sharedArray[0], sharedArray[1]);
// наприклад, 20 40
});worker.js
const { workerData } = require('worker_threads');
// workerData містить посилання на той самий SharedArrayBuffer
const arr = new Int32Array(workerData);
// Змінюємо значення в спільному буфері
arr[0] *= 2;
arr[1] *= 2;Тут main.js і worker.js працюють з однією й тією ж ділянкою пам'яті.
Зміни, зроблені в потоці, негайно видно в основному потоці.
2. Відмінність від ArrayBuffer
| Властивість | ArrayBuffer | SharedArrayBuffer |
|---|---|---|
| Копіюється при передачі | Так | Ні |
| Спільний доступ між потоками | Ні | Так |
Підтримка Atomics | Ні | Так |
| Безпека при паралельному записі | Не застосовується | Лише з Atomics |
| Типова мета | Буфер для одного потоку | Розділювана пам'ять між потоками |
3. Навіщо потрібен Atomics
Коли кілька потоків одночасно читають/пишуть спільні дані, може виникнути стан гонки (race condition).
Щоб уникнути цього, використовується об'єкт Atomics,
який виконує операції (читання, запис, інкремент тощо) атомарно -
тобто гарантує, що операція завершиться повністю, перш ніж почнеться інша.
Приклад:
const shared = new SharedArrayBuffer(4);
const arr = new Int32Array(shared);
Atomics.store(arr, 0, 5);
Atomics.add(arr, 0, 2);
console.log(Atomics.load(arr, 0)); // 74. Де застосовується SharedArrayBuffer
Корисний, коли:
- потрібно обмінюватися великими бінарними даними без копіювання;
- виконуються паралельні обчислення (рендеринг, симуляції, ML, парсинг);
- потрібна висока швидкість обміну між потоками (
worker_threads); - потрібно реалізувати розділюваний стан із синхронізацією через
Atomics.
Не потрібен, якщо:
- достатньо обміну повідомленнями (
postMessage); - дані прості (рядки, JSON, об'єкти);
- важливіша безпека, ніж продуктивність.
5. Переваги й недоліки
| Перевага | Недолік |
|---|---|
| Швидка передача даних без копіювання | Небезпечний за неправильної синхронізації |
| Економія пам'яті | Немає захисту від одночасного запису |
| Можливість атомарних операцій | Складніше в налагодженні й розумінні |
| Підтримується в браузерах і Node.js | Не можна передавати звичайні об'єкти |
6. Практичний приклад: лічильник між потоками
main.js
const { Worker } = require('worker_threads');
const shared = new SharedArrayBuffer(4);
const counter = new Int32Array(shared);
counter[0] = 0;
const worker1 = new Worker('./worker.js', { workerData: shared });
const worker2 = new Worker('./worker.js', { workerData: shared });
worker1.on('exit', () => worker2.on('exit', () => {
console.log('Результат:', counter[0]); // 2000000
}));worker.js
const { workerData } = require('worker_threads');
const counter = new Int32Array(workerData);
for (let i = 0; i < 1_000_000; i++) {
Atomics.add(counter, 0, 1);
}Обидва потоки безпечно збільшують один і той самий лічильник -
без гонок даних, завдяки Atomics.
Підсумок
| Характеристика | Опис |
|---|---|
| Призначення | Розділювана пам'ять між потоками |
| Тип | Об'єкт бінарної пам'яті |
| Сумісний з | TypedArray (Int8Array, Float64Array тощо) |
| Безпечна робота | Лише з Atomics |
| Де використовується | У Node.js (worker_threads), браузерах (Web Workers) |
| Переваги | Швидко, без копіювання, ефективно |
| Недоліки | Складніша логіка, ризик гонок даних |
Висновок:
SharedArrayBuffer- це "спільний шматок пам'яті", який кілька потоків можуть читати й змінювати одночасно. У Node.js він використовується разом ізworker_threadsіAtomics, коли потрібно обмінюватися даними швидко, без копіювання й з контролем синхронізації.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.