Sincronização em Java | Explicado

Sincronização em Java | Explicado
Quando começamos dois ou mais threads no mesmo programa, existe a possibilidade de que os vários threads tentem acessar o mesmo recurso e, consequentemente, resultados inconsistentes serão produzidos. E para fornecer comunicação confiável entre os vários threads, o conceito de sincronização é usado em java. A palavra -chave sincronizada em Java sincroniza as ações de vários threads e garante que apenas um thread possa acessar um recurso específico em um determinado momento.

Este artigo explorará os vários aspectos da sincronização em Java e, a esse respeito, este artigo abordará os seguintes conceitos:

  • O que é sincronização em Java?
  • Por que a sincronização é usada?
  • Por que a palavra -chave sincronizada é usada em java
  • Como usar a sincronização em java

Então, vamos conseguir

O que é sincronização em Java?

É um processo que controla o acesso de mais de um tópico para qualquer recurso compartilhado e, portanto, evita resultados inconsistentes.

Por que a sincronização é usada?

Em Java, o principal objetivo de usar a sincronização é evitar o comportamento inconsistente dos threads e impedir a interferência dos threads.

Por que a palavra -chave sincronizada é usada em java

Sincronizado é um modificador que pode ser aplicado apenas nos métodos e blocos e não pode ser aplicado em variáveis ​​e classes. Para entender este conceito

Como usar a sincronização em java

Vamos considerar alguns exemplos para uma compreensão profunda. Inicialmente, criaremos um programa Java muito simples para incrementar o valor do contador. Em seguida, estenderemos este exemplo ao cenário multithread. Gradualmente, iremos em direção à sincronização, onde aprenderemos por que a palavra -chave sincronizada é usada em java?

Exemplo
Neste exemplo, criaremos um programa simples que tenha uma variável contador e uma função definida pelo usuário incrementValue ().

Classificação da classe
int contador;
public void incrementValue ()
contador ++;


classe pública SynchronizationExample
public static void main (string [] args)
Contagem de contraclasse = new contraclass ();
contar.incrementValue ();
Sistema.fora.println ("contador:" + contagem.contador);

Sempre que invocamos o incrementValue () Isso aumentará o valor de contador por 1:

O valor do contador é incrementado com sucesso para 1, o que mostra a adequação do nosso programa. Se chamarmos o incrementValue () Método duas vezes, então o valor do contador 2. Da mesma forma, mostrará o valor do contador como 3 se chamarmos o incrementValue () Método três vezes como mostrado no snippet abaixo:

No trecho de código acima, invocamos o incrementValue () método quatro vezes, por isso mostra o valor do contador como 4.

Exemplo
Agora, vamos estender um pouco o exemplo acima, onde criaremos um tópico que chamará o incrementValue () dez vezes:

Classificação da classe
int contador;
public void incrementValue ()
contador ++;


classe pública SynchronizationExample
public static void main (string [] args) lança exceção
Contagem de contraclasse = new contraclass ();
Thread th1 = novo thread (new Runnable ()
public void run ()
para (int i = 1; i <= 10; i++)
contar.incrementValue ();


);
Th1.começar();
Th1.juntar();
Sistema.fora.println ("contador:" + contagem.contador);

No método de junção () de snippet () acima é usado com o objeto da classe Thread, para que um thread deve esperar até que o outro thread complete a execução. O snippet de código acima produz a seguinte saída:

Da saída, fica claro que o fio chama o incrementValue () dez vezes e, portanto, o valor do contador é igual a dez.

Até agora tudo bem, agora vamos considerar um ambiente multithread e criar mais um tópico para ver o que acontecerá quando dois tópicos exigirem o mesmo recurso (i.e. incrementValue () método) ao mesmo tempo.

Exemplo

Neste exemplo, temos dois threads chamam o método incrementValue () quinhentos vezes:

Classificação da classe
int contador;
public void incrementValue ()
contador ++;


classe pública SynchronizationExample
public static void main (string [] args) lança exceção
Contagem de contraclasse = new contraclass ();
Thread th1 = novo thread (new Runnable ()
public void run ()
para (int i = 1; i <= 500; i++)
contar.incrementValue ();


);
Thread th2 = novo thread (new Runnable ()
public void run ()
para (int i = 1; i <= 500; i++)
contar.incrementValue ();


);
Th1.começar();
Th1.juntar();
Th2.começar();
Th2.juntar();
Sistema.fora.println ("contador:" + contagem.contador);

Como ambos os threads estão chamando o contravalor () quinhentos vezes, tecnicamente, o valor do incremento deve ser mil. Vamos considerar o trecho abaixo para ver o que a saída diz:

Em vez de "1000", obtemos "753", agora o que isso significa? Por que não conseguimos o valor do contador como 1000?

Bem, é porque o multithreading suporta processamento paralelo e, portanto, há sempre a possibilidade de que ambos os fios busquem o valor do contador ao mesmo tempo e, portanto, ambos obtenham o mesmo valor do contador, nesse caso, em vez de incrementar o valor do contador duas vezes, aumenta apenas uma vez.

Então, como evitar esse cenário? Bem! Nesses casos, a palavra -chave sincronizada será usada.

Exemplo
Usaremos a palavra -chave sincronizada com a “incrementValue ()”Como resultado, apenas um thread acessará o“incrementValue ()”Método ao mesmo tempo. Todo o código permanecerá o mesmo do exemplo anterior, apenas a palavra -chave sincronizada será adicionada ao método incrementValue (), como mostrado no snippet:

public sincronizado void incrementValue ()
contador ++;

Agora, se o thread 1 estiver trabalhando com o incrementValue () Método então o thread 2 vai esperar, e vice -versa. Desta vez, obteremos a seguinte saída:

O trecho acima do dado mostra a eficácia da palavra-chave "sincronizada".

Conclusão

A sincronização é um processo que controla o acesso de mais de um thread e garante/verifica se apenas um thread pode acessar o recurso em um determinado momento. Para obter sincronização, a palavra -chave/modificador sincronizada é usada e pode ser aplicada aos métodos e blocos, mas não pode ser aplicada a variáveis ​​e classes. Em Java, o principal objetivo de usar a sincronização é evitar o comportamento inconsistente dos threads e impedir a interferência dos threads.