DEV Community

Sincronização e Usando métodos sincronizados

Conceito de Sincronização
A sincronização é necessária em programas multithreaded para coordenar o acesso a recursos compartilhados. Dois cenários comuns que exigem sincronização:

  • Acesso exclusivo a um recurso: Exemplo: evitar que duas threads gravem simultaneamente em um arquivo.
  • Cooperação entre threads: Exemplo: uma thread espera por um evento desencadeado por outra.

Java utiliza monitores para gerenciar sincronização, implementando bloqueios em objetos. Quando uma thread acessa um objeto sincronizado, ele é bloqueado, impedindo o acesso por outras threads até ser liberado.

Métodos Sincronizados
Os métodos sincronizados são declarados com a palavra-chave synchronized. Durante a execução:

  • A thread obtém o bloqueio do objeto.
  • Nenhuma outra thread pode acessar métodos sincronizados do mesmo objeto.
  • O objeto é desbloqueado quando a thread conclui o método.

Exemplo: Soma de um Array
O programa abaixo ilustra a sincronização usando um método chamado sumArray:

class SumArray {
  private int sum;
  synchronized int sumArray(int nums[]) {
    sum = 0;
    for (int i = 0; i < nums.length; i++) {
      sum += nums[i];
      System.out.println("Running total for " + Thread.currentThread().getName() + " is " + sum);
      try {
        Thread.sleep(10); // Alternância de tarefas
      } catch (InterruptedException exc) {
        System.out.println("Thread interrupted.");
      }
    }
    return sum;
  }
}

Enter fullscreen mode Exit fullscreen mode

Outras classes complementam o exemplo:

class MyThread implements Runnable {
  Thread thrd;
  static SumArray sa = new SumArray();
  int a[];
  int answer;

  MyThread(String name, int nums[]) {
    thrd = new Thread(this, name);
    a = nums;
    thrd.start();
  }

  public void run() {
    System.out.println(thrd.getName() + " starting.");
    answer = sa.sumArray(a);
    System.out.println("Sum for " + thrd.getName() + " is " + answer);
    System.out.println(thrd.getName() + " terminating.");
  }
}

class Sync {
  public static void main(String args[]) {
    int a[] = {1, 2, 3, 4, 5};
    MyThread mt1 = new MyThread("Child #1", a);
    MyThread mt2 = new MyThread("Child #2", a);
    try {
      mt1.thrd.join();
      mt2.thrd.join();
    } catch (InterruptedException exc) {
      System.out.println("Main thread interrupted.");
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

Saída do Programa com Sincronização
As threads acessam o método sumArray de forma ordenada:

Child #1 starting.
Running total for Child #1 is 1
...
Child #1 terminating.
Child #2 starting.
Running total for Child #2 is 1
...
Child #2 terminating.

Enter fullscreen mode Exit fullscreen mode

Problemas sem Sincronização
Removendo a palavra-chave synchronized de sumArray, múltiplas threads podem acessar o método ao mesmo tempo, causando resultados inconsistentes:

**Pontos Importantes sobre Métodos Sincronizados:**
Adicione synchronized antes da declaração do método.
Apenas uma thread pode executar métodos sincronizados de um objeto por vez.
Threads que tentarem acessar o método enquanto o objeto estiver bloqueado entrarão em estado de espera.
O bloqueio é liberado quando o método sincronizado termina.
Enter fullscreen mode Exit fullscreen mode

Top comments (0)