Perguntas Comuns sobre Multithreading em Java

Similaridades

  • Ambos os métodos podem pausar a execução de uma thread.

Diferenças

  1. Liberação de bloqueio:
    • O método sleep() não libera o bloqueio do objeto.
    • O método wait() libera o bloqueio do objeto.
  2. Finalidade:
    • wait() é geralemnte usado para comunicação/interação entre threads.
    • sleep() é geralmente usado para pausar a execução temproariamente.
  3. Retomada da execução:
    • Após a chamada de wait(), a thread não acorda automaticamente; é necessário que outra thread invoque notify() ou notifyAll() no mesmo objeto.
    • Após a execução de sleep(), a thread retoma automaticamente ou após um tempo limite especificado em wait(long timeout).
  4. Definição do método:
    • sleep() é um método estático da classe Thread.
    • wait() é um método da classe Object.

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.

Tags: java Multithreading Concorrência thread sleep

Publicado em 7-2 05:38