← Назад к вопросам

Зачем нужен метод join() из класса Thread?

1.0 Junior🔥 161 комментариев
#Многопоточность#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Метод join() в классе Thread

Метод join() используется для синхронизации потоков и позволяет одному потоку дождаться завершения другого потока перед продолжением своего выполнения.

Основное назначение

Когда вы вызываете thread.join(), текущий поток блокируется и ждёт, пока указанный поток thread завершит свою работу. После этого выполнение текущего потока продолжается.

Thread thread = new Thread(() -> {
    System.out.println("Фоновый поток начал работу");
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
    System.out.println("Фоновый поток завершил работу");
});

thread.start();
System.out.println("Главный поток продолжает работу");

try {
    thread.join(); // Главный поток ждёт завершения thread
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}

System.out.println("Главный поток может продолжить работу");

Примеры использования

1. Ожидание завершения одного потока:

Thread worker = new Thread(() -> {
    for (int i = 0; i < 5; i++) {
        System.out.println("Работник: " + i);
    }
});

worker.start();
worker.join(); // Ждём завершения
System.out.println("Все работы выполнены");

2. Ожидание нескольких потоков:

List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 5; i++) {
    final int taskId = i;
    Thread t = new Thread(() -> {
        System.out.println("Задача " + taskId + " выполняется");
    });
    threads.add(t);
    t.start();
}

// Ждём завершения всех потоков
for (Thread t : threads) {
    t.join();
}
System.out.println("Все задачи выполнены");

3. join() с timeout:

Thread longTask = new Thread(() -> {
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
});

longTask.start();

try {
    longTask.join(2000); // Ждём максимум 2 секунды
    if (longTask.isAlive()) {
        System.out.println("Поток всё ещё работает");
    } else {
        System.out.println("Поток завершился");
    }
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}

Ключевые особенности

  • Блокирующий вызов: Текущий поток теряет процессорное время, пока ждёт
  • InterruptedException: Если текущий поток прерван, выбрасывается исключение
  • Гарантия порядка: Обеспечивает happens-before отношение между потоками
  • Идеальен для координации: Часто используется в многопоточных приложениях для оркестрации потоков

Метод join() — это простой и надёжный способ синхронизации потоков в Java, хотя для более сложных сценариев используют CountDownLatch, Phaser или ExecutorService.

Зачем нужен метод join() из класса Thread? | PrepBro