A palavra-chave volátil desempenha um papel relativamente importante no Java multi-threading. A principal função do volátil é manter as variáveis visíveis em multi-threading e é o mecanismo de sincronização mais leve fornecido em Java.
Visibilidade
Todas as variáveis no modelo de memória de Java (as variáveis aqui são variáveis globais, não variáveis locais. Não há problema seguro para roscas no método, porque as variáveis são destruídas como o método é chamado) são armazenadas na memória principal. Cada encadeamento tem sua própria memória de trabalho. Cada vez que o encadeamento é executado, uma cópia da variável será obtida a partir da memória principal e a operação da variável será executada na memória de trabalho do encadeamento. Diferentes threads não podem compartilhar a memória de trabalho e só podem ler a cópia da variável da memória principal. Especificamente, pode ser expresso na figura abaixo:
However, for volatile (using synchronized/final modifications, the above rule is broken, that is, when the thread modifies the value of the variable, other threads can immediately know the change of the variable. However, for ordinary variables, when a thread modifies a variable, it is necessary to write the variable back to the main memory first, and other threads will only be visible to the thread after reading the variable from the main memory. It seems that from the above description, it pode-se deduzir que, desde que seja usada uma variável modificada por volátil, é garantido que a variável é segura para operar em um ambiente multithread, porque é visível para a memória de trabalho de todos os threads, ou seja, é consistente.
Public class Test {private estático volátil t = 0; private static int add () {return t ++; } public static void testVolatile () {for (int i = 0; i <20; i ++) {thread = novo thread (()-> {for (int j = 0; j <1000; j ++) {add ();}}); thread.start (); } while (thread.activeCount ()> 1) {thread.yield (); } System.out.println (t); } public static void main (string [] args) {testVolatile (); }}Espera -se que o valor T seja de 20.000, mas haverá uma situação em que o valor t é inferior a 20.000. Você deve adivinhar o motivo. O problema está no T ++. T ++ não é uma operação atômica. Em Java, a operação T ++ significa primeiro obter o valor t, depois adicione 1 e depois atribua t. Ao obter o valor t, ele é modificado por volátil, para que o valor mais recente do encadeamento possa ser obtido. No entanto, ao adicionar 1, não pode ser garantido. É possível que outros threads já tenham adicionado 1.
Então, qual cenário é o mais adequado para usar volátil?
* Na operação variável não depende do valor atual
* As variáveis não precisam participar de restrições invariantes com outras variáveis de estado
Traduzido para chinês significa que, para variáveis que têm leitura e gravação em multi-threads, você pode usar volátil para modificá-las. Dessa forma, você não deve usar operações de bloqueio/sincronizado para operações de leitura. A leitura diretamente é porque as variáveis são visíveis.