AtomicReference
-
12-12-2019 - |
Pergunta
Eu tenho algumas perguntas sobre AtomicReference.compareAndSet() método, de acordo com o documento, ele disse:
Atomicamente define o valor para o valor atualizado, se o valor actual == o valor esperado.
Tanto quanto eu entendo, o ==
operador está comparando o endereço de dois objetos, se sim, como será que vai funcionar em exemplos como este
private AtomicReference<AccessStatistics> stats =
new AtomicReference<AccessStatistics>(new AccessStatistics(0, 0));
public void incrementPageCount(boolean wasError) {
AccessStatistics prev, newValue;
do {
prev = stats.get();
int noPages = prev.getNoPages() + 1;
int noErrors = prev.getNoErrors;
if (wasError) {
noErrors++;
}
newValue = new AccessStatistics(noPages, noErrors);
} while (!stats.compareAndSet(prev, newValue));
}
Neste trecho de código, como é que a jvm sabe que campos de AccessStatistics
serão comparados no compareAndSet()
?Na verdade eu só estou querendo saber como é que isto é toda a estratégia de trabalho, dado o java não permite a substituição de ==
em tudo?Obrigado pelo comentários!
Solução
como é que a jvm sabe que campos de AccessStatistics devem ser comparados no compareAndSet()?
Não.Não é comparando os campos no objeto.É só comparar os referência do objeto, que é o que diz a documentação.Isso é apenas como a AtomicReference
classe funciona.Como você falar do javadocs, ele usa ==
e não o equals()
o método.
Atomicamente define o valor para o valor atualizado, se o valor actual == o valor esperado.
Todos os Atomic*
classes têm funções semelhantes.Ele permite que você atomicamente conjunto de valores, sendo certo que outra thread não substituir o seu valor.Com compareAndSet(...)
você tem que especificar o objeto atual de referência para garantir que você está atualizando conforme o esperado.
Em seu snippet de código, ele está tentando adicionar uma imutável de acesso-objeto de estatísticas.Portanto, ele é o valor atual, adiciona-lo e, em seguida, armazena a nova estatística para a referência.Se outro thread armazenados o seu estatísticas entre esse tempo, o compareAndSet
retornará falso e ele dá a volta e tenta de novo.Isto resolve condições de corrida, sem ter que ter um synchronized
bloco.
Outras dicas
A JVM não comparar os campos em tudo.Ele apenas compara se é ou não é a mesma referência, o mesmo ponteiro na memória, ou o que você quiser chamá-lo.