Насколько я знаю, в java нет методаожидания с предикатом, аналога std::condition_variable::wait из c++.
Допустим, я написал такой метсод с сигнатурой:
public void TimedWait(Object monitor, long timeout_msec, BooleanSupplier condition);
Далее, допустим, предикат внутри себя вычисляет какое-то значение, если оно не равно плохому, то возвращает true (т.е. необходимость остановить ожидание).
{
ValueType value = calculateValue();
return value.equals(badValue);
}
Предикат хочется сделать лямбдой, т.к. он маленький.
Допуcтим также, что, пока значение равно плохому, то calculateValue отрабатывает нормально и быстро, но после того, как будет получено нужное значение,
данные, из которых оно вычислено, необратимо меняются, и снова значение не получить.
Ну и наконец, допустим, что я хочу получить это значение после того, как отработал метод TimedWait.
Вопрос: как это сделать?
Допущения проистекают от дерьмового дизайна системы, и я этот дизайн переделаю, но остается чисто академический интерес.
А проблема вытащить занчение в том, что в лямбду можно передавать только константные переменные,
так что через замыкание вернуть значение красиво нельзя.
Варианты, которые вижу я:
1. Сделать какую-то обертку над значением, например, массив из одного элемента, или специальный класс,
его передать в предикат (ссылка на эту обертку будет константной), и в предикате выставить значение.
Т.е. как-то так:
ValueType[] wrapper = new ValueType[1];
TimedWait(monitor, timeout_msec, () -> {
wrapper[0] = calculateValue();
return !wrapper[0].equals(ифвValue);
});
Недостаток — выглядит криво.
2. Сделать предикат не лямбдой, а полноценным объектом спец. класса, значение передавать через поле класса.
Недостаток — лишний класс, слишком много лишнего кода.
3. Сделать доп. функцию (рядом с calculateValue), которая где-то сохраняет переданное значение, и вызывать ее внутри предиката.
Недостаток — лишняя функция, лишнее поле класса. Криво, в общем.
Мб есть какой-то красивый и идиоматичный способ решить подобную проблему.
Или вообще отказаться от лямбды с побочным эффектом, а сделать как-то еще?