logo

Palavra-chave volátil em Java

A palavra-chave volátil é usada para modificar o valor de uma variável por diferentes threads. Também é usado para tornar as classes thread-safe. Isso significa que vários threads podem usar um método e uma instância das classes ao mesmo tempo sem nenhum problema. A palavra-chave volátil pode ser usada com tipos primitivos ou objetos.

A palavra-chave volátil não armazena em cache o valor da variável e sempre lê a variável da memória principal. A palavra-chave volátil não pode ser usada com classes ou métodos. No entanto, é usado com variáveis. Também garante visibilidade e ordenação. Impede que o compilador reordene o código.

listar como array

O conteúdo do registro de dispositivo específico pode mudar a qualquer momento, portanto, você precisa da palavra-chave volátil para garantir que tais acessos não sejam otimizados pelo compilador.

Exemplo

 class Test { static int var=5; } 

No exemplo acima, suponha que dois threads estejam trabalhando na mesma classe. Ambos os threads são executados em processadores diferentes, onde cada thread possui sua cópia local de var. Se algum thread modificar seu valor, a alteração não refletirá no original na memória principal. Isso leva à inconsistência de dados porque o outro thread não tem conhecimento do valor modificado.

 class Test { static volatile int var =5; } 

No exemplo acima, variáveis ​​estáticas são membros de classe compartilhados entre todos os objetos. Existe apenas uma cópia na memória principal. O valor de uma variável volátil nunca será armazenado no cache. Todas as leituras e gravações serão feitas de e para a memória principal.

Quando usar?

  • Você pode usar uma variável volátil se quiser ler e escrever variáveis ​​longas e duplas automaticamente.
  • Pode ser usado como uma forma alternativa de obter sincronização em Java.
  • Todos os threads do leitor verão o valor atualizado da variável volátil após concluir a operação de gravação. Se você não estiver usando a palavra-chave volátil, threads de leitores diferentes poderão ver valores diferentes.
  • É usado para informar ao compilador que vários threads acessarão uma instrução específica. Impede que o compilador faça qualquer reordenação ou otimização.
  • Se você não usar a variável volátil, o compilador pode reordenar o código, ficando livre para escrever no cache o valor da variável volátil em vez de ler da memória principal.

Pontos importantes

  • Você pode usar a palavra-chave volátil com variáveis. Usar palavras-chave voláteis com classes e métodos é ilegal.
  • Garante que o valor da variável volátil sempre será lido da memória principal, não do cache de thread local.
  • Se você declarou a variável como volátil, as leituras e gravações são atômicas
  • Reduz o risco de erro de consistência de memória.
  • Qualquer gravação em variável volátil em Java estabelece um acontecimento antes do relacionamento com leituras sucessivas dessa mesma variável.
  • As variáveis ​​voláteis estão sempre visíveis para outros threads.
  • A variável volátil que é uma referência de objeto pode ser nula.
  • Quando uma variável não é compartilhada entre vários threads, você não precisa usar a palavra-chave volátil com essa variável.

Diferença entre sincronização e palavra-chave volátil

A palavra-chave volátil não substitui a palavra-chave sincronizada, mas pode ser usada como alternativa em certos casos. Existem as seguintes diferenças:

Palavra-chave volátil Palavra-chave de sincronização
A palavra-chave volátil é um modificador de campo. A palavra-chave sincronizada modifica blocos e métodos de código.
O thread não pode ser bloqueado para espera em caso de volatilidade. Threads podem ser bloqueados para espera em caso de sincronização.
Melhora o desempenho do thread. Os métodos sincronizados degradam o desempenho do thread.
Ele sincroniza o valor de uma variável por vez entre a memória do thread e a memória principal. Ele sincroniza o valor de todas as variáveis ​​entre a memória do thread e a memória principal.
Os campos voláteis não estão sujeitos à otimização do compilador. A sincronização está sujeita à otimização do compilador.

Exemplo de palavra-chave volátil

No exemplo a seguir, definimos uma classe que aumenta o valor do contador. O método run () em VolatileThread.java obtém o valor atualizado e o valor antigo quando o thread inicia a execução. Na classe principal, definimos o array de threads.

VolatileData.java

o que é hashset java
 public class VolatileData { private volatile int counter = 0; public int getCounter() { return counter; } public void increaseCounter() { ++counter; //increases the value of counter by 1 } } 

VolatileThread.java

 VolatileThread.java public class VolatileThread extends Thread { private final VolatileData data; public VolatileThread(VolatileData data) { this.data = data; } @Override public void run() { int oldValue = data.getCounter(); System.out.println('[Thread ' + Thread.currentThread().getId() + ']: Old value = ' + oldValue); data.increaseCounter(); int newValue = data.getCounter(); System.out.println('[Thread ' + Thread.currentThread().getId() + ']: New value = ' + newValue); } } 

VolatileMain.java

 public class VolatileMain { private final static int noOfThreads = 2; public static void main(String[] args) throws InterruptedException { VolatileData volatileData = new VolatileData(); //object of VolatileData class Thread[] threads = new Thread[noOfThreads]; //creating Thread array for(int i = 0; i <noofthreads; ++i) threads[i]="new" volatilethread(volatiledata); for(int i="0;" < noofthreads; threads[i].start(); starts all reader threads threads[i].join(); wait for } pre> <p> <strong>Output:</strong> </p> <pre> [Thread 9]: Old value = 0 [Thread 9]: New value = 1 [Thread 10]: Old value = 1 [Thread 10]: New value = 2 </pre> <hr></noofthreads;>