Qual é a diferença entre variáveis voláteis e atômicas?
sobes.tech IA
Resposta da IA
volatile garante a visibilidade das alterações de uma variável para diferentes threads e proíbe o compilador e a JVM de reordenar as instruções relacionadas com essa variável. Isso garante que, ao ler uma variável volatile, o thread verá o valor mais recente escrito. No entanto, volatile não garante a atomicidade de operações compostas (por exemplo, incremento).
As classes atómicas do pacote java.util.concurrent.atomic (como AtomicInteger, AtomicLong, AtomicReference) usam operações atómicas de baixo nível, como Compare-And-Swap (CAS), que são realizadas ao nível de hardware. Elas garantem que as operações de leitura-modificação-escrita sejam feitas de forma atómica, sem necessidade de sincronização explícita com synchronized.
Comparação:
| Característica | volatile |
Variáveis atómicas (AtomicInteger, etc.) |
|---|---|---|
| Atomicidade | Não garante a atomicidade de operações compostas. | Garantem a atomicidade de operações (CAS). |
| Visibilidade | Garante a visibilidade das mudanças para outros threads. | Garantem a visibilidade (efeito secundário de CAS). |
| Uso | Para garantir a visibilidade em leituras/escritas simples. | Para operações atómicas como incremento, CAS. |
| Custos adicionais | Menor custo que synchronized. |
Geralmente menor custo que synchronized em condições de baixa concorrência. |
Exemplo de uso de volatile:
class SharedData {
volatile boolean flag = false; // Garante a visibilidade da alteração de flag
public void setFlag() {
flag = true;
}
public boolean isFlag() {
return flag;
}
}
Exemplo de uso de AtomicInteger:
import java.util.concurrent.atomic.AtomicInteger;
class Counter {
AtomicInteger count = new AtomicInteger(0); // Contador atómico
public void increment() {
count.incrementAndGet(); // Incremento atómico
}
public int getCount() {
return count.get();
}
}