Volátil: por que impedir o código de reordenamento do compilador

Em java, com o meu conhecimento, variável volátil faz um thread ler / gravar diretamente para a CPU principal (não no cache de cada thread), então faça sua mudança visível para outros threads.

A coisa que eu não sei é: Então, por que esse trabalho (de volátil) pode impedir a declaração de código do compilador / CPU reordenar.

obrigado 🙂

Aqui está um bom exemplo que ilustra a questão que a proibição de reordenar tem como objective abordar (tirada daqui ):

 class VolatileExample { int x = 0; volatile boolean v = false; public void writer() { x = 42; v = true; } public void reader() { if (v == true) { //uses x - guaranteed to see 42. } } } 

Neste exemplo, v é volátil, mas x não é. Se escritor e leitor são executados simultaneamente e o leitor vê v definido como true , x é garantido como 42 . Antes do Java-5, o compilador estava livre para reordenar as gravações em x e v , então você poderia ver x em zero depois de ver v definido como true . Isso foi confuso e levou a erros sutis. O modelo de memory Java-5 solucionou esse problema, tornando as gravações voláteis quase equivalentes à synchronization.

É assim que a linguagem é definida. Informalmente, marcar uma variável volatile em Java informa especificamente ao compilador que ele não deve reordenar as instruções em torno dele ou otimizar seu valor, uma vez que esse valor pode ser modificado simultaneamente em outro thread. A implementação particular da JVM é então responsável por respeitar esse modificador volatile e tomar as devidas precauções para não otimizar incorretamente o programa.

Se você quiser obter detalhes mais específicos sobre as garantias em nível de idioma existentes para garantir que a volatile funcione corretamente, consulte a descrição do modelo de memory Java da Java Language Specification , que define as regras abstratas que regem o comportamento do encadeamento. Também descreve como a volatile interage com essas regras.

Espero que isto ajude!