#java
#java
Вопрос:
Существуют ли существующие фреймворки, реализующие следующий подход?
public class WaitableContainer<T> {
private T object;
public <T> peekAwait() {...} // returns object if object !=null or makes the caller thread sleep until object != null
public actuate(T object) {
this.object = object; // here all sleeping threads must awake and receive the new object
}
}
Нужна какая-то объектная оболочка, которая заставит вызывающий поток отключаться до тех пор, пока другой поток не установит объект.
Комментарии:
1. Я думаю, что интерфейс BlockingQueue может быть полезен (по крайней мере, для первого метода). Я действительно не понимаю, что должен делать actuate
2. также вы можете попробовать java Future
3. Похоже, что это работа для
CyclicBarrier
4. При проектировании предполагается, что какой-то поток может пропустить объект, если он еще не вызывался
peekAwait
. Это правда? Готовы ли вы к сценарию, когда выactuate
создаете объект, но некому его просмотреть, и он исчезает?
Ответ №1:
Это звучит как завершаемое будущее.
// container.actuate(o); becomes
future.complete(o);
// container.peekAwait(); becomes
future.get();
Если вы не можете использовать Java 8, FutureTask — достойный выбор для обхода, но вместо явной настройки вы предоставляете вызываемый объект, который возвращает значение, которое вы хотите установить.
final FutureTask<Object> lazyLoadedData = new FutureTask<>(() -> expensiveIO());
...
if (!lazyLoadedData.isDone()) {
synchronized(lazyLoadedData) {
if (!lazyLoadedData.isDone()) {
// run() does the computation and sets the data
// essentially, lazyLoadedData.set(expensiveIO())
lazyLoadedData.run();
}
}
}
// Data is available
lazyLoadedData.get();
Если вы планируете, чтобы это делал ExecutorService, он уже возвращает Future;
final FutureTask<Object> future = executorService.submit(() -> expensiveIO());
// Now you just need to call get()
future.get();