"Olá, amigo!"

"Oi, Rishi!"

"Vou apresentá-lo aos métodos wait , notify e notifyAll da classe Object."

"Hoje vamos apenas nos familiarizar com eles, mas voltaremos mais tarde e passaremos mais tempo nisso."

"OK."

"Esses métodos foram inventados como parte do mecanismo de sincronização de threads."

"Deixe-me lembrá-lo de que Java possui um mecanismo interno para controlar o acesso a recursos compartilhados (objetos) de diferentes threads. Um thread pode declarar que um objeto está ocupado e outros threads terão que esperar até que o objeto ocupado seja liberado. "

"Eu me lembro. Você faz isso usando a palavra-chave sincronizada ."

"Certo. Normalmente, o código seria mais ou menos assim:"

public void print()
{
 Object monitor = getMonitor();
 synchronized(monitor)
 {
  System.out.println("text");
 }
}

"Lembra como isso funciona?"

"Sim. Se dois threads chamarem simultaneamente o método print(), um deles entrará no bloco rotulado como sincronizado e bloqueará o monitor, o que faz com que o segundo thread espere até que o monitor seja liberado."

"Certo. Uma vez que um thread entra no bloco rotulado como sincronizado, o objeto monitor é marcado como ocupado e outros threads serão forçados a esperar que o objeto monitor seja liberado. O mesmo objeto monitor pode ser usado em várias partes do programa. "

"A propósito, por que você escolheu o nome monitor?"

"Um monitor é o que você costuma chamar de objeto que armazena o status de ocupado ou livre."

"E é aqui que os métodos de espera e notificação entram em ação."

"Na verdade, esses são realmente os dois únicos métodos. Os outros são apenas adaptações desses métodos."

"Agora vamos entender o que é o método wait e por que precisamos dele. "

"Às vezes, há situações em um programa em que uma thread entra em um bloco de código sincronizado e trava o monitor, mas não consegue continuar porque está faltando algum dado. Por exemplo, um arquivo que ela precisa processar não terminou de baixar ou algo parecido."

"Podemos apenas esperar que o arquivo seja baixado. Você pode apenas verificá-lo usando um loop. Se o arquivo ainda não foi baixado, durma por um segundo ou mais e verifique novamente até que seja baixado."

"Algo assim:"

while(!file.isDownloaded())
{
 Thread.sleep(1000);
}
processFile(file);

"Mas, em nosso caso, esse tipo de espera é muito caro. Como nosso thread bloqueou o monitor, outros threads também são forçados a esperar, mesmo que já tenham os dados de que precisam."

"O método wait () foi inventado para resolver este problema. Este método faz com que o thread libere o monitor e depois «suspenda» o thread.

"Você só pode chamar o método de espera de um objeto monitor quando o monitor estiver ocupado, ou seja, somente dentro de um bloco sincronizado . Quando isso acontece, o thread para temporariamente de executar e o monitor é liberado para que outros threads possam usá-lo."

"Muitas vezes, há instâncias em que um thread entra em um bloco sincronizado e chama em espera, liberando assim o monitor."

"Então um segundo fio entrará e será suspenso, depois um terceiro e assim por diante."

"E como um tópico é retomado?"

"Para isso, existe um segundo método: notificar."

"Você só pode chamar os métodos notify / notifyAll de um objeto monitor quando o monitor está ocupado, ou seja, somente dentro de um bloco sincronizado . O método notifyAll desperta todos os threads que estão esperando neste objeto monitor."

"O método notify 'descongela' um thread aleatório, mas o método notifyAll descongela todos os threads «congelados» deste monitor."

"Muito interessante. Obrigado, Rishi."

"Há também adaptações do método wait():"

método wait() Explicação
void wait(long timeout)
A thread «congela», mas automaticamente «descongela» depois de esperar o número de milissegundos passado para o método como argumento.
void wait(long timeout, int nanos)
A thread «congela», mas automaticamente «descongela» depois de esperar o número de nanossegundos passados ​​ao método como argumento.

"Também chamamos isso de espera com tempo limite. O método funciona como uma espera normal, mas se o tempo especificado tiver passado e o thread não tiver sido ativado, ele será ativado sozinho."