junior
Даны 3 потока Т1, Т2 и Т3. Как реализовать выполнение в последовательности Т1, Т2, Т3?
Существует несколько способов обеспечить последовательное выполнение потоков.
Способ 1: Thread.join() (самый простой)
Метод join() блокирует вызывающий поток до завершения целевого потока.
Пример
Thread t1 = new Thread(() -> System.out.println("T1"));
Thread t2 = new Thread(() -> System.out.println("T2"));
Thread t3 = new Thread(() -> System.out.println("T3"));
t1.start();
t1.join(); // Ждём завершения T1
t2.start();
t2.join(); // Ждём завершения T2
t3.start();
t3.join(); // Ждём завершения T3
Способ 2: join() внутри потоков
Каждый поток вызывает join() на предыдущем:
Пример
Thread t1 = new Thread(() -> System.out.println("T1"));
Thread t2 = new Thread(() -> {
try { t1.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
System.out.println("T2");
});
Thread t3 = new Thread(() -> {
try { t2.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
System.out.println("T3");
});
// Порядок запуска не важен!
t3.start();
t2.start();
t1.start();
Способ 3: CountDownLatch
Пример
CountDownLatch latch1 = new CountDownLatch(1);
CountDownLatch latch2 = new CountDownLatch(1);
Thread t1 = new Thread(() -> {
System.out.println("T1");
latch1.countDown();
});
Thread t2 = new Thread(() -> {
try { latch1.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
System.out.println("T2");
latch2.countDown();
});
Thread t3 = new Thread(() -> {
try { latch2.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
System.out.println("T3");
});
t3.start(); t2.start(); t1.start();
Способ 4: ExecutorService с одним потоком
Пример
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> System.out.println("T1"));
executor.submit(() -> System.out.println("T2"));
executor.submit(() -> System.out.println("T3"));
executor.shutdown();
newSingleThreadExecutor() гарантирует выполнение задач строго последовательно в порядке их подачи.
На собеседовании наиболее ожидаемый ответ — через
join(). Но если упомянетеCountDownLatchилиSingleThreadExecutor, это покажет знание инструментовjava.util.concurrent.