<h2>SharedArrayBuffer: O Que É e Por Que Usar</h2>
<p>SharedArrayBuffer é um objeto JavaScript que permite compartilhar um buffer de memória entre múltiplos workers (threads). Diferentemente dos Web Workers comuns, que comunicam-se por cópia de dados (postMessage), o SharedArrayBuffer oferece acesso direto à mesma região de memória, eliminando overhead de serialização. Isso é essencial em aplicações CPU-intensivas, processamento de vídeo, simulações 3D e análise de grandes datasets em tempo real.</p>
<p>A principal vantagem é o desempenho: múltiplos workers podem ler e modificar os mesmos dados simultaneamente sem cópias custosas. Porém, com grande poder vem grande responsabilidade — você herda problemas clássicos de programação paralela como race conditions e deadlocks. É aqui que entra a API Atomics.</p>
<h2>Configurando SharedArrayBuffer</h2>
<h3>Criação Básica</h3>
<p>Para criar um SharedArrayBuffer, você instancia-o como um TypedArray. Diferentemente de ArrayBuffer comum, este é compartilhável entre contextos:</p>
<pre><code class="language-javascript">// main.js
const sharedBuffer = new SharedArrayBuffer(32); // 32 bytes
const sharedArray = new Int32Array(sharedBuffer);
// Inicializa dados
sharedArray[0] = 100;
// Cria e passa para worker
const worker = new Worker('worker.js');
worker.postMessage({ sharedBuffer });</code></pre>
<pre><code class="language-javascript">// worker.js
self.onmessage = (event) => {
const { sharedBuffer } = event.data;
const sharedArray = new Int32Array(sharedBuffer);
console.log('Valor inicial:', sharedArray[0]); // 100
sharedArray[0] = 200; // Modifica diretamente na memória compartilhada
};</code></pre>
<h3>Restrições de Segurança</h3>
<p>Por questões de segurança (mitigação de Spectre), navegadores modernos exigem headers específicos. O servidor deve retornar:</p>
<pre><code>Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp</code></pre>
<h2>Atomics: Operações Thread-Safe</h2>
<p>A API Atomics fornece métodos que garantem operações indivisíveis (atômicas) sobre SharedArrayBuffer, prevenindo race conditions. Os principais são <code>load</code>, <code>store</code>, <code>compareExchange</code>, <code>wait</code> e <code>notify</code>.</p>
<h3>Operações Básicas Atômicas</h3>
<pre><code class="language-javascript">// main.js
const sharedBuffer = new SharedArrayBuffer(8);
const sharedArray = new Int32Array(sharedBuffer);
// Escrita atômica
Atomics.store(sharedArray, 0, 42);
// Leitura atômica
const value = Atomics.load(sharedArray, 0);
console.log(value); // 42
// Compare-and-swap (atualiza se valor == esperado)
const wasUpdated = Atomics.compareExchange(sharedArray, 0, 42, 100);
console.log(wasUpdated); // 42 (valor anterior)
console.log(Atomics.load(sharedArray, 0)); // 100</code></pre>
<p>Sem Atomics, leituras/escritas simples (<code>sharedArray[0] = 42</code>) não são garantidas como thread-safe em todas as arquiteturas. Atomics garante que a operação completa atomicamente antes de qualquer outra instrução interferir.</p>
<h3>Wait e Notify: Sincronização Entre Threads</h3>
<p>O padrão mais poderoso é usar <code>wait()</code> e <code>notify()</code> para sincronização produtor-consumidor:</p>
<pre><code class="language-javascript">// main.js (produtor)
const sharedBuffer = new SharedArrayBuffer(4);
const sharedArray = new Int32Array(sharedBuffer);
const worker = new Worker('worker.js');
worker.postMessage({ sharedBuffer });
// Simula produção
setTimeout(() => {
Atomics.store(sharedArray, 0, 42);
Atomics.notify(sharedArray, 0); // Acorda workers aguardando
}, 1000);</code></pre>
<pre><code class="language-javascript">// worker.js (consumidor)
self.onmessage = (event) => {
const { sharedBuffer } = event.data;
const sharedArray = new Int32Array(sharedBuffer);
console.log('Esperando dados...');
Atomics.wait(sharedArray, 0, 0); // Bloqueia até notify ou timeout
const value = Atomics.load(sharedArray, 0);
console.log('Recebi:', value); // 42
};</code></pre>
<p><code>Atomics.wait()</code> só funciona em Workers, nunca na thread principal (evita congelamento da UI). Quando <code>notify()</code> é chamado, todos os workers aguardando aquele índice são acordados.</p>
<h2>Caso de Uso Prático: Pipeline de Processamento</h2>
<p>Imagine processar frames de vídeo com múltiplos workers. Cada worker processa um quadro diferentes enquanto compartilham estado de progresso:</p>
<pre><code class="language-javascript">// main.js
const FRAME_COUNT = 100;
const sharedBuffer = new SharedArrayBuffer(4 * 3); // 3 Int32s
const state = new Int32Array(sharedBuffer); // [framesProcessadas, erros, pausado]
// Inicia 4 workers
const workers = Array.from({ length: 4 }, () => {
const w = new Worker('frame-processor.js');
w.postMessage({ sharedBuffer, totalFrames: FRAME_COUNT });
return w;
});
// Monitor progress
setInterval(() => {
const processed = Atomics.load(state, 0);
console.log(Progresso: ${processed}/${FRAME_COUNT});
}, 500);</code></pre>
<pre><code class="language-javascript">// frame-processor.js
self.onmessage = (event) => {
const { sharedBuffer, totalFrames } = event.data;
const state = new Int32Array(sharedBuffer);
for (let i = 0; i < totalFrames; i++) {
// Processa frame
processFrame(i);
// Incremento atômico do contador
Atomics.add(state, 0, 1);
}
};
function processFrame(index) {
// Simulação: processamento pesado
let sum = 0;
for (let i = 0; i < 1000000; i++) sum += Math.sqrt(i);
}</code></pre>
<h2>Conclusão</h2>
<p>SharedArrayBuffer e Atomics são ferramentas poderosas para paralelismo real em JavaScript. Primeira aprendizagem: <strong>SharedArrayBuffer elimina cópias de dados</strong>, permitindo que múltiplos workers acessem a mesma memória. Segunda: <strong>Atomics garante operações thread-safe</strong> e fornece primitivas de sincronização (wait/notify). Terceira: <strong>use esse padrão apenas quando necessário</strong> — overhead de sincronização pode degradar performance em casos triviais. Domine esses conceitos e você dominará computação paralela em JavaScript.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer" target="_blank" rel="noopener noreferrer">MDN: SharedArrayBuffer</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics" target="_blank" rel="noopener noreferrer">MDN: Atomics API</a></li>
<li><a href="https://html.spec.whatwg.org/multipage/workers.html" target="_blank" rel="noopener noreferrer">WHATWG: HTML Living Standard - Workers</a></li>
<li><a href="https://developer.chrome.com/docs/workbox/worker-performance/" target="_blank" rel="noopener noreferrer">Web Workers Performance Guide - Google Developers</a></li>
<li><a href="https://javascript.info/web-workers" target="_blank" rel="noopener noreferrer">JavaScript.info: Web Workers</a></li>
</ul>