Que métodos de combate à condição de corrida de threads, além do uso da palavra-chave volatile, conhece?
sobes.tech IA
Resposta da IA
Existem várias abordagens principais para sincronização de threads e prevenção de condições de corrida no Android, além de volatile.
-
Uso de synchronized: Bloqueia o acesso ao código ou método para outros threads até que o thread atual termine.
// Método sincronizado synchronized void incrementCounter() { counter++; } // Bloco sincronizado void updateData() { synchronized (this) { // ou outro objeto monitor // código que requer sincronização } } -
Uso de classes do pacote
java.util.concurrent.locks: Oferecem mecanismos de bloqueio mais flexíveis quesynchronized.import java.util.concurrent.locks.ReentrantLock; private final ReentrantLock lock = new ReentrantLock(); void performLockedOperation() { lock.lock(); // Aquisição do bloqueio try { // Código protegido pelo bloqueio } finally { lock.unlock(); // Liberação do bloqueio (importante no finally) } } -
Uso de classes do pacote
java.util.concurrent.atomic: Fornecem operações atômicas que são executadas como uma única unidade sem interrupções por outros threads. Adequadas para operações simples sobre tipos primitivos e referências.import java.util.concurrent.atomic.AtomicInteger; private final AtomicInteger atomicCounter = new AtomicInteger(0); void incrementAtomicCounter() { atomicCounter.incrementAndGet(); // Incremento atômico } -
Uso de coleções seguras para threads: Coleções do pacote
java.util.concurrent(por exemplo,ConcurrentHashMap,CopyOnWriteArrayList) projetadas para uso seguro em ambientes multithread sem sincronização explícita pelo desenvolvedor.import java.util.concurrent.ConcurrentHashMap; import java.util.Map; private final Map<String, Integer> concurrentMap = new ConcurrentHashMap<>(); void updateMap(String key, Integer value) { concurrentMap.put(key, value); // operação segura de escrita } -
**Uso de
**ThreadLocal**: Permite criar uma variável que terá uma cópia separada para cada thread. Assim, cada thread trabalha com sua própria cópia de dados, evitando a corrida.private final ThreadLocal<Integer> threadLocalValue = new ThreadLocal<Integer>() { @Override protected Integer initialValue() { return 0; // Valor inicial para cada thread } }; void processData() { int value = threadLocalValue.get(); value++; threadLocalValue.set(value); // Definir valor para o thread atual }
A escolha do método depende da natureza da tarefa, da necessidade de bloqueio, do tipo de dados e do desempenho requerido.