Concorrência e Multithreading em Java: Guia Completo

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
Here is the translated HTML content in Portuguese (Português), with all HTML tags preserved and only the text content translated. Programming terms, code examples, and proper nouns remain in English. ```html

Concorrência e Multithreading em Java: da teoria à prática



No mundo moderno do software, o desempenho das aplicações depende diretamente da capacidade de usar eficientemente os recursos do processador. Concorrência e multithreading em Java são conceitos-chave que permitem executar várias tarefas simultaneamente, acelerar o processamento de dados e criar interfaces de usuário responsivas. Neste artigo, vamos explorar os principais mecanismos de multithreading em Java, aprender a criar e gerenciar threads, e discutir as melhores práticas para evitar erros comuns.



O que é uma thread e como criá-la em Java?



Uma thread é um processo leve que é executado dentro de uma única aplicação. Cada thread tem sua própria pilha de chamadas e pode operar independentemente de outras threads. Em Java, existem duas maneiras principais de criar uma thread.



Método 1: Herdando da classe Thread

public class MyThread extends Thread {    @Override    public void run() {        System.out.println("Thread " + getName() + " iniciada!");    }

public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); // Iniciar a thread }}


Método 2: Implementando a interface Runnable

public class MyRunnable implements Runnable {    @Override    public void run() {        System.out.println("Thread executando via Runnable");    }

public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); thread.start(); }}


Recomenda-se usar o segundo método, pois ele não requer herança e permite implementar várias interfaces simultaneamente.



Sincronização de threads: evitando race condition



Quando várias threads acessam dados compartilhados ao mesmo tempo, ocorre uma condição de corrida (race condition). Para evitar isso, o Java fornece mecanismos de sincronização.



Palavra-chave synchronized

Bloqueia o acesso a um método ou bloco de código para outras threads até que a thread atual termine a execução:

public class Counter {    private int count = 0;

public synchronized void increment() { count++; }

public synchronized int getCount() { return count; }}


Bloqueios com Lock

Um mecanismo mais flexível que synchronized. Permite definir timeouts e tentar adquirir um bloqueio sem bloquear:

import java.util.concurrent.locks.ReentrantLock;

public class SafeCounter { private final ReentrantLock lock = new ReentrantLock(); private int count = 0;

public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); // Sempre liberar o bloqueio } }}


Pool de threads e ExecutorService



Criar uma nova thread para cada tarefa é uma operação cara. Para gerenciar threads de forma eficiente, use ExecutorService do pacote java.util.concurrent.



import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;

public class ThreadPoolExample { public static void main(String[] args) { // Criar um pool de 4 threads ExecutorService executor = Executors.newFixedThreadPool(4);

for (int i = 0; i < 10; i++) { final int taskId = i; executor.submit(() -> { System.out.println("Tarefa " + taskId + " executando em " + Thread.currentThread().getName()); }); }

executor.shutdown(); // Finalizar o pool após executar todas as tarefas }}


Principais tipos de pools:

  • newFixedThreadPool(n) — número fixo de threads
  • ```

Blogs

Book Recommendations