Как приостановить поток до тех пор, пока условие не станет истинным, без ожидания?

Как приостановить поток до тех пор, пока условие не станет истинным, без ожидания? Например, предположим, что я проверяю, есть ли

playerOne.isWalking ()

Будет правдой, и я хочу запустить некоторый код, когда он станет правдой. Снова предположим, что playerOne - это экземпляр класса Player, который затем имеет функцию isWalking (). У меня нет доступа к тому, что делает isWalking () истинным. Поэтому каждый раз, когда я хочу проверить, истинно ли isWalking (), я должен явно вызывать метод из экземпляра player.

Я пробовал использовать Wait / Notify в синхронизированных блоках, но это никогда не сработало, потому что мне пришлось бы вручную уведомлять поток о пробуждении, когда isWalking () становится истинным, и я не знаю, когда это станет истинным.

Я пробовал использовать шаблон наблюдателя, чтобы сделать Player подклассом наблюдаемого, чтобы я мог вызывать метод обновления, когда isWalking () становится истинным, но снова я не знаю, когда это произойдет.

Я даже пробовал использовать свойства, но это тоже не сработало.

Возможно ли это проверить без ожидания занятости? Постоянно опрашивать и вызывать эту функцию, чтобы убедиться, что она истинна, а затем, если она истинна, выполнить код.

Это было плохое решение, связанное с ожиданием занятости:

Решение для ожидания занятости


person TheAppFoundry    schedule 09.07.2017    source источник
comment
Добро пожаловать в Stack Overflow! Просмотрите тур, осмотритесь и прочитайте справочный центр, в частности Как задать хороший вопрос? и О чем я могу спросить здесь?.   -  person Timothy Truckle    schedule 09.07.2017


Ответы (1)


Основная проблема заключается в том, что вы используете метод getter для получения информации и действий с ней. Здесь нарушается принцип Говори, а не спрашивай!.

ОО способ решить эту проблему - ввести интерфейс (например: PlayerMovingListener).

Класс игрока будет содержать экземпляр объекта, реализующего этот интерфейс (или их список). Как только игрок начинает ходить, он вызывает метод isMoving(), определенный в интерфейсе, реализованном (или всеми) объектами слушателя, удерживаемыми плеером.
Скорее всего, запускается методом установки в вашем текущем Payer реализация.

person Timothy Truckle    schedule 09.07.2017
comment
Я ценю быстрый ответ. У меня нет доступа к сеттеру, если он есть в текущей реализации Player из API, который я использую. public boolean isInCombat() { /* compiled code */ } isInCombat () - это функция isWalking (), о которой я говорил, просто переименованная для ясности. Остались ли варианты? - person TheAppFoundry; 09.07.2017
comment
У меня нет доступа к сеттеру, если он есть в текущей реализации Player из API, который я использую. - Вы не можете реализовать шаблон прослушивателя только на одной стороне. Класс Player должен предоставить инфраструктуру для обработки слушателей. ИМХО ваша программа нарушена дизайном. - person Timothy Truckle; 09.07.2017
comment
Это сломано по дизайну. Это отвечает на него! - person TheAppFoundry; 09.07.2017