Olá! Para ver como o syncronized(this) funciona, comentei ele no segundo método para ver o que iria acontecer:
package br.com.alura.banheiro.principal;
public class Banheiro {
public void fazerNumero1() {
String nome = Thread.currentThread().getName() + " ";
System.out.println(nome + "batendo na porta");
synchronized(this) {
System.out.println(nome + "entrando no banheiro");
System.out.println(nome + "fazendo coisa rápida");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(nome + "dando descarga");
System.out.println(nome + "lavando a mão");
System.out.println(nome + "saindo do banheiro");
}
}
public void fazerNumero2() {
String nome = Thread.currentThread().getName() + " ";
System.out.println(nome + "batendo na porta");
//synchronized(this) {
System.out.println(nome + "entrando no banheiro");
System.out.println(nome + "fazendo coisa demorada");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(nome + "dando descarga");
System.out.println(nome + "lavando a mão");
System.out.println(nome + "saindo do banheiro");
//}
}
}
Maria é do método 1 e João é do método 2.
No programa principal, Maria chamou a tarefa primeiro e João depois:
package br.com.alura.banheiro.principal;
public class Principal {
public static void main(String[] args) {
Banheiro banheiro = new Banheiro();
Thread thread1 = new Thread(new TarefaNumero1(banheiro), "Maria");
Thread thread2 = new Thread(new TarefaNumero2(banheiro), "João");
thread1.start();
thread2.start();
}
}
Só que o primeiro método (Maria) está com syncronized(this). Então eu achei que o thread da Maria iria executar o método inteiro de forma atômica, para só depois executar o thread do João; mas quando rodei o o programa Principal, uma thread 'esbarrou' na outra.
O resultado foi esse:
Maria batendo na porta
Maria entrando no banheiro
Maria fazendo coisa rápida
João batendo na porta
João entrando no banheiro
João fazendo coisa demorada
Maria dando descarga
Maria lavando a mão
Maria saindo do banheiro
João dando descarga
João lavando a mão
João saindo do banheiro
A minha dúvida é por quê é necessário utilizar syncronized(this) nos dois métodos (fazerNumero1() e fazerNumero2()) se o syncronized faz o código dentro dele ser executado do início ao fim?