Чтобы напрямую ответить на первые два вопроса в вашем посте, прослушиватели удаления запускаются в произвольный момент времени после того, как элементы удалены из кэша, поэтому вы не можете использовать прослушиватели удаления для атомарной повторной вставкизначение.
- Безопасно ли повторно вставлять запись кэша, которая удаляется во время обратного вызова RemovalListener?
Да, это безопасно;вызов .put()
изнутри RemovalListener
никак не нарушит кеш.Вообще говоря, у Cache
нет проблем с одновременными мутациями .
Если это так, это потокобезопасно, так что нет никакого способа, которым CacheLoader мог бы создать второе значение для этого ключа, пока обратный вызов RemovalListener все еще происходит в другом потоке?
Нетмутации, вызванные RemovalListener
, не являются атомарными в отношении ассоциированного удаления.Мало того, что другой поток может получить доступ к кешу между завершением удаления и получателем уведомлений, возможно, что между этими двумя действиями существует значительная задержка.Как в вики упоминается " операции прослушивания удаления выполняются синхронно [во время] обслуживания кеша ". продолжает , чтобы сказать, что задачи обслуживания выполняются небольшими партиями, и не предоставляется никаких гарантий относительно того, когда (или неявно, если) они действительно будут выполняться.
Есть ли лучший способ добиться того, чего я хочу?Это не строго / только «кеш» - важно, чтобы для каждого ключа использовалось одно и только одно значение, но я также хочу кэшировать запись в течение некоторого времени после завершения задания, которое оно представляет.
Как вы говорите, на самом деле это не кеш (или, точнее, кеш удаления).Если есть объекты, которые вы не хотите выселять, просто не храните их в кэше для выселения.Как Луи предлагает использовать настройку с двумя структурами данных с картой для текущих процессов, а удаленный кеш для завершенных процессов будет делать именно то, что вам нужно.