Concorrência e Multithreading em JavaScript: Event Loop e Worker Threads

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: Mitos e Realidade da Multithreading em JavaScript

O JavaScript é tradicionalmente associado a um modelo de execução single-thread. Muitos desenvolvedores, especialmente aqueles vindos do mundo C++ ou Java, consideram isso uma limitação. No entanto, o ecossistema moderno do Node.js oferece ferramentas poderosas para trabalhar com concorrência e, mais importante, com verdadeira multithreading. Neste artigo, vamos analisar como funciona o Event Loop, quando usar Worker Threads e como construir aplicações de alta carga corretamente.

Ao contrário da multithreading clássica, onde cada thread tem sua própria pilha e pode ser executada em paralelo em diferentes núcleos da CPU, o JavaScript no navegador e no Node.js usa o modelo de concorrência baseada em eventos. No entanto, com o surgimento do módulo worker_threads no Node.js, obtivemos a capacidade de paralelismo real.



Parte Principal



1. Event Loop: O Coração da Concorrência no Node.js

O Event Loop é um mecanismo que permite ao Node.js executar operações de entrada e saída (I/O) não bloqueantes, apesar da single-thread do JavaScript. Ele verifica constantemente a fila de tarefas e as executa à medida que chegam.

As principais fases do Event Loop:

  • Timers — execução de callbacks agendados via setTimeout() e setInterval().
  • I/O callbacks — tratamento de operações de I/O concluídas.
  • Idle, prepare — fases internas do Node.js.
  • Poll — obtenção de novos eventos de I/O e execução de seus callbacks.
  • Check — execução de callbacks setImmediate().
  • Close callbacks — tratamento de eventos de fechamento (por exemplo, socket.on('close', ...)).

Exemplo de funcionamento do Event Loop:

const fs = require('fs');

console.log('Início do programa');

setTimeout(() => { console.log('Timer disparou');}, 0);

setImmediate(() => { console.log('setImmediate executado');});

fs.readFile(__filename, () => { console.log('Arquivo lido');});

console.log('Fim do programa');

// Saída:// Início do programa// Fim do programa// setImmediate executado// Timer disparou// Arquivo lido

É importante entender: o Event Loop não torna o código multi-thread, ele apenas distribui eficientemente o tempo entre as tarefas. Se uma tarefa ocupar a CPU por muito tempo (por exemplo, um loop complexo), todo o Event Loop é bloqueado.



2. O Problema do Bloqueio e a Solução: Worker Threads

Para tarefas intensivas em CPU (criptografia, processamento de imagens, parsing de grandes dados), o Event Loop não é adequado — ele bloquearia todo o servidor. É aqui que entram as Worker Threads.

Worker Threads é um módulo do Node.js que permite criar threads reais do sistema operacional. Cada worker tem sua própria instância do V8 e Event Loop, permitindo a execução paralela do código.

Exemplo básico de uso de Worker Threads:

// main.jsconst { Worker } = require('worker_threads');

function runWorker(workerData) { return new Promise((resolve, reject) => { const worker = new Worker('./worker.js', { workerData }); worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) { reject(new Error(`Worker parou com código ${code}`)); } }); });}

async function main() { console.log('Iniciando worker...'); const result = await runWorker(42); console.log('Resultado:', result);}

main().catch(console.error);

// worker.jsconst { parentPort, workerData } = require('worker_threads');

// Tarefa intensiva em CPUfunction fibonacci(n) { if (n < 2) return n; return fibonacci(n - 1) + fibonacci(n -

Blogs

Book Recommendations