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;
}
}
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.");
}
}
}
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.
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.
Top comments (0)