Sobes.tech
Middle

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();
    }
}