Мой код имеет поток пользовательского интерфейса, который обновляет логическую переменную. Проблема, с которой я сталкиваюсь, заключается в том, что я хочу, чтобы основная программа продолжала выполняться, когда переменная становится истинной.
public static void main(String[] args) throws Exception{
//Display the UI by creating an instance of Node
Node node = new Node();
//Wait for the node to connect to a router before continuing
while(!isConnectedToRouter);
//Do other things
}
Во время отладки я заметил, что основной поток приостанавливается, поэтому главная никогда не доходит до "Делать другие вещи". Даже после другого потока логическое значение isConnectedToRouter истинно. Если я изменил цикл while на
//Wait for the node to connect to a router before continuing
while(!isConnectedToRouter){
Thread.sleep(1);
}
Это работает, но это заставляет меня осознавать, что я делаю что-то неправильно. Любая помощь будет оценена по достоинству.
Лучше, чем ожидание ждет спать в основном потоке, пока не наступит время.
java.util.concurrent имеет интерфейсы уровня высокого уровня для потоковой передачи, которые легче использовать безопасно и подходят для большинства ситуаций.
Ожидание с помощью CountDownLatch, например, может быть выполнено следующим образом:
CountDownLatch latch = new CountDownLatch(1);
этот объект должен быть видимым как в основном потоке, так и в вашем рабочем столе. Блокировка должна выполняться с использованием одного и того же объекта.
Ожидание в основной теме:
latch.await();
И когда другая нить готова:
latch.countDown();
Преимущество этой реализации состоит в том, что вам не нужно беспокоиться о том, когда рабочий поток готов до начала фазы ожидания. В этой ситуации await()
делает правильную вещь и немедленно возвращается.
В этой ситуации также могут использоваться старые методы низкого уровня из Object
, но для обращения к случаю, когда рабочий поток будет готов до того, как основной поток будет ждать, будет требоваться особая осторожность - без проверки того, что было бы легко заблокировать основной нить. Поэтому я рекомендую придерживаться java.util.concurrent
, если у вас нет веских причин. Эти классы существуют, чтобы помочь написать безопасный код потока.
Примечание. Я оставил код обработки InterruptedExceptions
для краткости - это должно выполняться как с latch.wait()
и с Object.wait()
Вы должны сделать логический volatle, чтобы основной поток мог прочитать последнее значение этой логической переменной, а не просто считывать значения в регистрах.
isConnectedToRouter
объявлен какvolatile
?