Ответ
В Java ожидание ответа или завершения операции можно реализовать несколькими способами, выбор зависит от контекста: многопоточность, асинхронность или тестирование.
Основные подходы:
-
Thread.sleep()— простейшая блокировка потока на указанное время. Не рекомендуется для production-кода, так как поток бесполезно занят.Thread.sleep(1000); // Поток блокируется на 1 секунду -
wait()/notify()— механизм ожидания по условию в рамках синхронизированного блока.synchronized (lockObject) { while (!conditionMet) { lockObject.wait(); // Освобождает монитор и ждет notify() } // Условие выполнено, продолжаем работу } -
FutureиCompletableFuture— для асинхронных вычислений. Методget()блокирует поток до получения результата.CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return longRunningOperation(); }); String result = future.get(); // Блокирующее ожидание -
CountDownLatch,CyclicBarrier,Semaphore— высокоуровневые синхронизаторы изjava.util.concurrentдля координации потоков.CountDownLatch latch = new CountDownLatch(1); // В другом потоке после выполнения задачи: latch.countDown(); // Ожидание в основном потоке: latch.await();
Для тестирования удобно использовать библиотеку Awaitility, которая позволяет декларативно описывать ожидания.
await().atMost(5, SECONDS).until(() -> service.isReady());
Рекомендация: В production-коде предпочтительны асинхронные подходы (CompletableFuture, реактивные стримы) или специализированные синхронизаторы, чтобы избежать бесполезной блокировки потоков.