Acredito que os leitores que entendem de multithreading Java saberão claramente seu papel. A palavra-chave volátil é usada para declarar variáveis de tipo simples, como int, float, boolean e outros tipos de dados. Se esses tipos de dados simples forem declarados voláteis, as operações neles se tornarão atômicas. Mas isso tem certas limitações. Por exemplo, n no exemplo a seguir não é atômico:
Copie o código do código da seguinte forma:
pacote mitoread;
classe pública JoinThread estende Thread
{
público estático volátil int n = 0;
execução de vazio público ()
{
para (int i = 0; i < 10; i++)
tentar
{
n=n+1;
sleep(3); // Para tornar os resultados da execução mais aleatórios, atrase 3 milissegundos
}
pegar (Exceção e)
{
}
}
public static void main(String[] args) lança exceção
{
Tópico tópicos[] = new Tópico[100];
for (int i = 0; i < threads.length; i++)
//Cria 100 tópicos
threads[i] = new JoinThread();
for (int i = 0; i < threads.length; i++)
//Executa os 100 threads recém-criados
tópicos[i].start();
for (int i = 0; i < threads.length; i++)
//Continua após todos os 100 threads terem sido executados
threads[i].join();
System.out.println("n=" + JoinThread.n);
}
}
Se a operação em n for atômica, o resultado final da saída deverá ser n=1000. No entanto, ao executar o código de área acima, a saída n geralmente é menor que 1000, o que mostra que n=n+1 não é uma operação de nível atômico. . A razão é que para uma variável simples declarada volátil, se o valor atual estiver relacionado ao valor anterior da variável, então a palavra-chave volátil não terá efeito, o que significa que as seguintes expressões não são operações atômicas:
Copie o código do código da seguinte forma:
n=n+1;
n++;
Se você quiser tornar esta situação uma operação atômica, você precisa usar a palavra-chave sincronizada. O código acima pode ser alterado para o seguinte formato:
Copie o código do código da seguinte forma:
pacote mitoread;
classe pública JoinThread estende Thread
{
público estático int n = 0;
público estático sincronizado void inc()
{
n++;
}
execução de vazio público ()
{
para (int i = 0; i < 10; i++)
tentar
{
inc(); // n = n + 1 alterado para inc();
sleep(3); // Para tornar os resultados da execução mais aleatórios, atrase 3 milissegundos
}
pegar (Exceção e)
{
}
}
public static void main(String[] args) lança exceção
{
Tópico tópicos[] = new Tópico[100];
for (int i = 0; i < threads.length; i++)
//Cria 100 tópicos
threads[i] = new JoinThread();
for (int i = 0; i < threads.length; i++)
//Executa os 100 threads recém-criados
tópicos[i].start();
for (int i = 0; i < threads.length; i++)
//Continua após todos os 100 threads terem sido executados
threads[i].join();
System.out.println("n=" + JoinThread.n);
}
}
O código acima muda n=n+1 para inc(), onde o método inc usa a palavra-chave sincronizada para sincronização de métodos. Portanto, tenha cuidado ao usar a palavra-chave volátil. Isso não significa que variáveis de tipo simples sejam modificadas com volátil. Todas as operações nesta variável são as operações originais quando o valor da variável é determinado pela sua anterior, como n=. n+1 , n++, etc., a palavra-chave volátil será inválida. A operação na variável é de nível atômico apenas quando o valor da variável não tem nada a ver com seu valor anterior. é o nível original. Portanto, você deve ter cuidado ao usar chaves voláteis. Se não tiver certeza, você pode usar sincronizadas em vez de voláteis.