Similaridades
- Ambos os métodos podem pausar a execução de uma thread.
Diferenças
- Liberação de bloqueio:
- O método
sleep()não libera o bloqueio do objeto. - O método
wait()libera o bloqueio do objeto.
- O método
- Finalidade:
wait()é geralemnte usado para comunicação/interação entre threads.sleep()é geralmente usado para pausar a execução temproariamente.
- Retomada da execução:
- Após a chamada de
wait(), a thread não acorda automaticamente; é necessário que outra thread invoquenotify()ounotifyAll()no mesmo objeto. - Após a execução de
sleep(), a thread retoma automaticamente ou após um tempo limite especificado emwait(long timeout).
- Após a chamada de
- Definição do método:
sleep()é um método estático da classeThread.wait()é um método da classeObject.
Exemplos de código
Exemplo com sleep()
// Exemplo demonstrando o uso do método sleep()
public class ExemploSleep {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
try {
System.out.println("A thread1 vai dormir por 3 segundos.");
Thread.sleep(3000);
System.out.println("A thread1 acordou.");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread1.start();
}
}
Exemplo com wait() e notify()
// Exemplo demonstrando o uso dos métodos wait() e notify()
public class ExemploWaitNotify {
private static final Object RECURSO = new Object();
public static void main(String[] args) {
Thread consumidor = new Thread(() -> {
synchronized (RECURSO) {
try {
System.out.println("Thread consumidor esperando pelo recurso.");
RECURSO.wait();
System.out.println("Thread consumidor recebeu notificação.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread produtor = new Thread(() -> {
synchronized (RECURSO) {
try {
Thread.sleep(1500); // Garante que o consumidor comece a esperar primeiro
System.out.println("Thread produtor enviando notificação.");
RECURSO.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
consumidor.start();
produtor.start();
}
}
Por que o método wait() não está definido na classe Thread?
O método wait() coloca uma thread que possui o bloqueio de um objeto em estado de espera, liberando automaticamente o bloqueio do objeto atual. Cada objeto em Java possui um bloqueio intrínseco, portanto, é necessário operar no objeto correspondente (Object) e não na thread atual (Thread). ### Análise do código-fonte
public final void wait(long tempoEspera) throws InterruptedException {
if (tempoEspera < 0) {
throw new IllegalArgumentException("valor de tempo limite é negativo");
}
// Método nativo para colocar a thread em estado de espera
waitInternal(tempoEspera);
}
O método wait() internamente chama o método nativo waitInternal, projetado para fazer a thread esperar e liberar o bloqueio do objeto. ### Pergunta relacionada: Por que o método sleep() está definido na classe Thread?
Porque sleep() apenas pausa a execução da thread atual, não envolvendo aquisição ou liberação de bloqueios de objetos. Por essa razão, foi projetado como um método estático da classe Thread. Podemos chamar diretamente o método run() da classe Thread?
Chamar diretamente o método run() não inicia uma nova thread; ele executa o conteúdo do método run() no thread de chamada atual. Portanto, isso não implementa o efeito de multithreading. ### Exemplo de código
// Exemplo comparando run() e start()
public class ExemploRunVsStart {
public static void main(String[] args) {
Thread tarefa = new Thread(() -> {
System.out.println("Executando em uma thread separada.");
});
// Chamada direta ao método run - executa no thread principal
tarefa.run();
// Chamada ao método start - cria uma nova thread
tarefa.start();
}
}
Conclusão: A chamada ao método start() inicia a thread e a coloca em estado pronto, enquanto a execução direta do método run() não ocorre de forma multithread.