Estou tentando entender como funciona o sincronismo e o bloqueio de objetos.
No exemplo abaixo, tentei colocar as minhas observações para ver se entendo passo a passo o que ocorre no código.
Se alguem puder dar uma olhada no código e comentar as partes que não entendi ( com ??? ) ou algum comentário errado, agradeço muito.
A minha principal dúvida é:
Quem bloqueia quem?
Quando os bloqueios são liberados ?
Quando tenho o bloqueio de b, o que isso quer dizer (além de que nenhuma thread pode acessar ele enquanrto não desbloquear) ?
Segue o código:
package testKiller7;
public class ThreadA { // classe ThreadA que possue a thread main "principal"
public static void main(String[] args) { // método main
ThreadB b = new ThreadB(); // criado novo objeto do tipo Thread
b.start(); // colocando a thread "b" em estado executável
synchronized (b) { // bloco sincronizado que obtem o bloqueio de "b"
try {
System.out.println("Aguardando por b para terminar de rodar");
b.wait(); // aguarde "b" terminar para continuar
} catch (InterruptedException e) {
}
System.out.println("Total é:" + b.total); // imprime variavel total
}
}
}
class ThreadB extends Thread { // classe ThreadB que é uma thread
int total; // variável de instância chamada total
@Override
public void run() { // método que é executado quando acionado b.start
synchronized (this) { // bloco sincronizado que obtém o bloqueio de ????
for (int i = 0; i <= 100; i++) { // loop contador
total += i; // total = total + i
}
notify(); // notifica a thread main(é isso ???) que a thread b terminou.
}
}
}
Mas o que temos que ter em mente é que nesse problema temos três “atores”: O monitor, a thread main e a threadB.
O monitor é o camarada que permite que a thread “da vez” seja executada. A thread main (ThreadA) é a thread da vez. Quando a threadB é instanciada e na linha 6 (b.start() ela passa para o estado de RUNNABLE, mas quem tá executando ainda é a threadA.
O fluxo é encaminhado para o synchronized e ocorre o “b.wait();”. Isso faz com que o monitor dê permissão para threadB ser executada com o bloco interno synchronized seja exclusivo e a thread main (ThreadA) receba o bloqueio até ser notificado enquanto ao término da threadB (notify(); linha 28 ).
Mas o que temos que ter em mente é que nesse problema temos três “atores”: O monitor, a thread main e a threadB.
O monitor é o camarada que permite que a thread “da vez” seja executada. A thread main (ThreadA) é a thread da vez. Quando a threadB é instanciada e na linha 6 (b.start() ela passa para o estado de RUNNABLE, mas quem tá executando ainda é a threadA.
O fluxo é encaminhado para o synchronized e ocorre o “b.wait();”. Isso faz com que o monitor dê permissão para threadB ser executada com o bloco interno synchronized seja exclusivo e a thread main (ThreadA) receba o bloqueio até ser notificado enquanto ao término da threadB (notify(); linha 28 ).