У меня есть расчетная карта (с мягкие значения), который я использую для кэширования результатов дорогостоящего вычисления.
Теперь у меня есть ситуация, когда я знаю, что конкретный ключ, скорее всего, будет рассмотрен в течение следующих нескольких секунд. Этот ключ также более дорог для вычисления, чем большинство.
Я хотел бы заранее вычислить значение в потоке с минимальным приоритетом, чтобы при запросе значения он уже был кэширован, улучшив время отклика.
Что такое хороший способ сделать это, чтобы:
- У меня есть контроль над потоком (в частности, его приоритетом), в котором выполняется вычисление.
- Дублировать работу можно избежать, т.е. вычисление выполняется только один раз. Если задача вычисления уже запущена, то вызывающий поток ожидает эту задачу вместо вычисления значения снова (
FutureTask
реализует это. С помощью вычислений Guava это верно, если вы вызываете толькоget
, но нет, если вы смешиваете его с вызовами доput
.) - Метод "вычислять значение заранее" является асинхронным и идемпотентным. Если вычисление уже выполняется, оно должно немедленно вернуться, не дожидаясь завершения этого вычисления.
- Избегать инверсии приоритета, например. если поток с высоким приоритетом запрашивает значение, а поток среднего приоритета выполняет что-то несвязанное, но задача вычисления ставится в очередь на поток с низким приоритетом, поток с высоким приоритетом не должен быть голоден. Возможно, это может быть достигнуто путем временного повышения приоритета вычислительного потока (ов) и/или выполнения вычисления в вызывающем потоке.
Как это можно скоординировать между всеми задействованными нитями?
Дополнительная информация
Вычисления в моем приложении - операции фильтрации изображений, что означает, что все они связаны с процессором. Эти операции включают в себя аффинные преобразования (от 50 мкс до 1 мс) и свертки (до 10 мс). Конечно, эффективность различных приоритетов потоков зависит от способности ОС упреждать более крупные задачи.