Sabemos que as operações de configuração de valores de variáveis em Java são operações atômicas, exceto para variáveis de tipo longo e duplo. Em outras palavras, não há necessidade de sincronizar operações simples de leitura e gravação de valores de variáveis.
Antes da JVM 1.2, a implementação do modelo de memória Java sempre lia variáveis da memória principal, o que não exigia atenção especial. Com a maturidade e otimização da JVM, o uso de palavras-chave voláteis tornou-se muito importante em ambientes multithread. No modelo de memória Java atual, os threads podem armazenar variáveis na memória local (como registros de máquina) em vez de ler e escrever diretamente na memória principal. Isso pode fazer com que um thread modifique o valor de uma variável na memória principal, enquanto outro thread continua a usar sua cópia do valor da variável no registro, causando inconsistência de dados. Para resolver este problema, basta declarar a variável como volátil (instável) como neste programa. Isso indica à JVM que esta variável é instável e será armazenada na memória principal sempre que for utilizada para leitura. De um modo geral
Portanto, em um ambiente multitarefa, os sinalizadores compartilhados entre tarefas devem ser modificados com voláteis.
Cada vez que uma variável de membro modificada por Volatile é acessada por um thread, o valor da variável de membro é forçado a ser relido na memória compartilhada. Além disso, quando uma variável de membro é alterada, o thread é forçado a gravar o valor alterado de volta na memória compartilhada. Dessa forma, a qualquer momento, dois threads diferentes sempre veem o mesmo valor de uma variável membro.
A especificação da linguagem Java afirma: Para obter velocidade ideal, os threads podem salvar cópias privadas de variáveis de membros compartilhados e compará-las com os valores originais das variáveis de membros compartilhados somente quando o thread entra ou sai de um bloco de código sincronizado.
Dessa forma, quando vários threads interagem com um objeto ao mesmo tempo, deve-se prestar atenção para permitir que os threads obtenham alterações nas variáveis de membros compartilhados em tempo hábil.
A palavra-chave volátil avisa a VM: ela não pode salvar uma cópia privada desta variável de membro, mas deve interagir diretamente com a variável de membro compartilhada.
Sugestão de uso: Use volátil em variáveis de membro acessadas por duas ou mais threads. Não é necessário utilizar quando a variável a ser acessada já estiver em um bloco de código sincronizado ou for uma constante.
Como o uso de volátil bloqueia a otimização de código necessária na VM, ele é menos eficiente, portanto, esta palavra-chave deve ser usada somente quando necessário.
Na implementação da máquina virtual, tipos básicos como int e char têm uma palavra de comprimento. E long e double ocupam duas palavras de comprimento. Em algumas implementações de máquinas virtuais, os dois comprimentos de palavra podem ser tratados como dois comprimentos atômicos de palavra única.
Se long e double não forem modificados com volátil, se vários threads acessarem a variável, o resultado será confuso devido à não atomicidade geral da operação longa.
Por exemplo: int, um thread escreve 4 e outro escreve 5. O valor final deve ser 4 ou 5. E o tipo longo pode ser um valor confuso.