No livro Java efetivo, ele afirma:
A especificação da linguagem garante que a leitura ou gravação de uma variável seja atômica, a menos que a variável seja do tipo
long
oudouble
[JLS, 17.4.7].
O que significa "atômico" no contexto da programação Java ou programação em geral?
volatile long
ouvolatile double
tornando a leitura atômica e a gravação atômica.Respostas:
Aqui está um exemplo, porque um exemplo geralmente é mais claro do que uma explicação longa. Suponhamos que
foo
é uma variável do tipolong
. A operação a seguir não é uma operação atômica:De fato, a variável é escrita usando duas operações separadas: uma que escreve os primeiros 32 bits e a segunda que escreve os últimos 32 bits. Isso significa que outro encadeamento pode ler o valor de
foo
e ver o estado intermediário.Tornar a operação atômica consiste em usar mecanismos de sincronização para garantir que a operação seja vista, a partir de qualquer outro encadeamento, como uma única operação atômica (isto é, não dividida em partes). Isso significa que qualquer outro encadeamento, uma vez que a operação seja atômica, verá o valor de
foo
antes da atribuição ou após a atribuição. Mas nunca o valor intermediário.Uma maneira simples de fazer isso é tornar a variável volátil :
Ou para sincronizar todos os acessos à variável:
Ou, para substituí-lo por um
AtomicLong
:fonte
"Operação atômica" significa uma operação que parece instantânea da perspectiva de todos os outros threads. Você não precisa se preocupar com uma operação parcialmente completa quando a garantia se aplica.
fonte
É algo que "parece que o resto do sistema ocorre instantaneamente" e se enquadra na categorização de Linearizabilidade nos processos de computação. Para citar mais esse artigo vinculado:
Assim, por exemplo, no contexto de um sistema de banco de dados, é possível ter 'confirmações atômicas', o que significa que você pode enviar um conjunto de alterações de atualizações para um banco de dados relacional e essas alterações serão todas enviadas ou nenhuma no caso de falha, dessa maneira os dados não se corrompem e, consequentemente, de bloqueios e / ou filas, a próxima operação será uma gravação ou leitura diferente, mas somente após o fato. No contexto de variáveis e encadeamento, isso é o mesmo, aplicado à memória.
Sua cotação destaca que esse comportamento não precisa ser esperado em todas as instâncias.
fonte
Acabei de encontrar um post Operações atômicas vs. operações não atômicas para ser muito útil para mim.
fonte
Se você tiver vários threads executando os métodos m1 e m2 no código abaixo:
você tem a garantia de que qualquer chamada de thread
m2
será 0 ou 5.Por outro lado, com este código (onde
i
é um longo):uma chamada de encadeamento
m2
pode ler 0, 1234567890L ou algum outro valor aleatório, porquei = 1234567890L
não é garantido que a instrução seja atômica para along
(uma JVM pode gravar os primeiros 32 bits e os últimos 32 bits em duas operações e um encadeamento pode ser observadoi
no meio) .fonte
Em Java, os campos de todos os tipos de leitura e gravação, exceto long e double, ocorrem atomicamente, e se o campo for declarado com o modificador volátil, mesmo long e double serão lidos e gravados atomicamente. Ou seja, obtemos 100% do que estava lá ou do que aconteceu lá, nem pode haver nenhum resultado intermediário nas variáveis.
fonte