Atualizado: 02/11/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Gerenciamento de Threads em Java

A classe Thread fornece diversos métodos para o controle e o gerenciamento de threads em execução. Entre eles, destacam-se os métodos sleep() e join(), que permitem pausar a execução e coordenar a finalização de threads de forma previsível.

Método sleep

O método estático Thread.sleep() suspende temporariamente a execução da thread atual por um período especificado de tempo. Existem três versões desse método:

static void sleep(long millis)
static void sleep(long millis, int nanos)
static void sleep(Duration duration)

A primeira versão recebe como parâmetro o número de milissegundos. A segunda adiciona um valor em nanossegundos ao tempo total de pausa. A terceira utiliza um objeto Duration para representar a duração da suspensão.

Esse método pode lançar uma exceção do tipo InterruptedException, o que significa que o bloqueio pode ser interrompido antes de seu término. Por isso, o código que chama sleep() deve tratar ou declarar essa exceção.

Exemplo:

class MyTask implements Runnable {

    public void run() {

        String name = Thread.currentThread().getName();

        System.out.println(name + " started...");

        System.out.println(name + " works");

        try {
            Thread.sleep(1000); // pausa por 1000 milissegundos
        }
        catch (InterruptedException ex) {
            System.out.println(ex.getMessage());
        }

        System.out.println(name + " finished...");
    }
}

public class Program {

    public static void main(String[] args) {

        System.out.println("Main thread started...");

        var task = new MyTask();
        new Thread(task, "MyTask").start();

        System.out.println("Main thread finished...");
    }
}

No exemplo acima, o método run() contém uma pausa de um segundo. Quando a execução chega a Thread.sleep(1000), a thread é temporariamente suspensa e retomará sua execução apenas após o tempo determinado. A saída será semelhante a:

Main thread started...
Main thread finished...
MyTask started...
MyTask works
MyTask finished...

Método join

Nos exemplos anteriores, a thread principal (main) terminava antes das threads criadas. Em muitos casos, é desejável que a thread principal finalize apenas depois que todas as threads secundárias concluírem suas tarefas. Para isso, existe o método join().

Esse método também possui variações:

void join()
void join(long millis)
void join(long millis, int nanos)
boolean join(Duration duration)

Independentemente da versão, join() faz com que a thread que o chama aguarde a finalização da thread sobre a qual foi aplicado. Caso um tempo limite seja definido, a espera não ultrapassará esse intervalo.

Exemplo:

class MyTask implements Runnable {

    public void run() {

        String name = Thread.currentThread().getName();

        System.out.println(name + " started...");

        System.out.println(name + " works");

        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException ex) {
            System.out.println(ex.getMessage());
        }

        System.out.println(name + " finished...");
    }
}

public class Program {

    public static void main(String[] args) {

        System.out.println("Main thread started...");

        var task = new MyTask();
        var t = new Thread(task, "MyTask");
        t.start();

        try {
            t.join(); // a thread principal aguarda a finalização da thread t
        }
        catch (InterruptedException ex) {
            System.out.println(ex.getMessage());
        }

        System.out.println("Main thread finished...");
    }
}

A saída será:

Main thread started...
MyTask started...
MyTask works
MyTask finished...
Main thread finished...

A chamada de join() faz com que a thread principal espere até que MyTask termine antes de continuar. Assim, o encerramento ocorre em ordem previsível.

Também é possível limitar o tempo de espera. No exemplo abaixo, a thread principal aguardará no máximo 500 milissegundos pela conclusão de MyTask:

var task = new MyTask();
var t = new Thread(task, "MyTask");
t.start();

try {
    t.join(500); // espera no máximo 500 ms
}
catch (InterruptedException ex) {
    System.out.println(ex.getMessage());
}

Como o tempo de execução da tarefa é maior que 500 milissegundos, a thread principal encerrará antes que MyTask termine.

Main thread started...
MyTask started...
MyTask works
Main thread finished...
MyTask finished...

Aguardando múltiplas threads

Se o programa cria várias threads e é necessário que a principal finalize apenas após todas elas concluírem, basta chamar join() para cada uma.

class MyTask implements Runnable {

    public void run() {

        String name = Thread.currentThread().getName();

        System.out.println(name + " started...");

        System.out.println(name + " works");

        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException ex) {
            System.out.println(ex.getMessage());
        }

        System.out.println(name + " finished...");
    }
}

public class Program {

    public static void main(String[] args) {

        System.out.println("Main thread started...");

        Thread[] tasks = new Thread[4];
        for (int i = 0; i < tasks.length; i++) {

            tasks[i] = new Thread(new MyTask(), "MyTask_" + i);
            tasks[i].start();
        }

        try {
            for (Thread t : tasks) t.join();
        }
        catch (InterruptedException ex) {
            System.out.println(ex.getMessage());
        }

        System.out.println("Main thread finished...");
    }
}

A execução mostrará que a thread principal só termina após todas as threads secundárias:

Main thread started...
MyTask_2 started...
MyTask_1 started...
MyTask_2 works
MyTask_1 works
MyTask_3 started...
MyTask_3 works
MyTask_0 started...
MyTask_0 works
MyTask_1 finished...
MyTask_2 finished...
MyTask_3 finished...
MyTask_0 finished...
Main thread finished...

Resumo

  • O método Thread.sleep() pausa temporariamente a execução da thread atual.
  • Esse método lança InterruptedException, que deve ser tratado.
  • O método join() faz uma thread aguardar a finalização de outra.
  • É possível definir um tempo máximo de espera ao usar join(long millis).
  • Para coordenar múltiplas threads, é necessário chamar join() para cada uma delas.
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com