O que são bloqueios otimistas e pessimistas?
sobes.tech IA
Resposta da IA
Os bloqueios otimistas e pessimistas são abordagens para gerir o acesso paralelo a dados partilhados em ambientes concorrentes (aplicações multithread, bases de dados).
Bloqueio pessimista:
Supõe que os conflitos ao aceder aos dados são prováveis. Antes de aceder a um recurso, o thread ou transação bloqueia-o (de forma exclusiva ou partilhada). Outros threads que tentem aceder a ele esperarão até que o bloqueio seja libertado.
- Vantagens: Garante a integridade dos dados, é simples de implementar em ambientes com baixa concorrência.
- Desvantagens: Pode causar bloqueios (esperas), reduzir a capacidade de processamento em alta concorrência (deadlocks).
- Exemplos: a palavra-chave
synchronizedem Java, bloqueios ao nível de linhas ou tabelas em bases de dados.
// Exemplo de bloqueio pessimista em Java
public class Counter {
private int count = 0;
public synchronized void increment() {
count++; // Bloqueio no objeto, apenas um thread pode executar este método de cada vez
}
public synchronized int getCount() {
return count;
}
}
Bloqueio otimista:
Supõe que os conflitos ao aceder aos dados são pouco prováveis. O acesso aos dados é feito sem bloqueios. Antes de guardar alterações, verifica-se se os dados foram modificados por outro thread desde que foram lidos. Se ocorrerem alterações, a operação é cancelada e geralmente tentada novamente (retry).
- Vantagens: Alta capacidade de processamento em ambientes com baixa concorrência, sem problemas de deadlocks.
- Desvantagens: Podem surgir conflitos que requerem reintentos, o que complica a lógica. Não é adequado para operações de longa duração ou com alta probabilidade de conflitos.
- Exemplos: operações Compare-And-Swap (CAS), gestão de versões em bases de dados (por exemplo, uso de colunas de versão ou marcas de tempo).
// Exemplo de bloqueio otimista usando CAS (java.util.concurrent.atomic)
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicCounter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
// Tentativa de incrementar de forma atómica
// Se o valor mudou entre a leitura e a atualização, a tentativa é reexecutada
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
}
Comparação:
| Característica | Bloqueio pessimista | Bloqueio otimista |
|---|---|---|
| Suposição | Os conflitos são prováveis | Os conflitos são pouco prováveis |
| Abordagem | Bloqueio até ao acesso | Acesso sem bloqueio, verificação na escrita |
| Em ambientes de alta concorrência | Pode causar bloqueios, reduzir a capacidade | Repetições frequentes, reduzir o desempenho |
| Em ambientes de baixa concorrência | Pode criar sobrecarga | Alta capacidade de processamento |
| Problema de deadlock | Possível | Impossível (do ponto de vista do acesso concorrente a recursos) |