Кэш ExpiringMap или TTL

http://www.java2s.com/Code/Java/Collections-Data-Structure/ExpiringMap.htm

Q1) Я смотрел на приведенный выше код кэширования. Я запутался, зачем нам нужна блокировка при вызове getLastAccessTime. Этот метод вызывается только потоком Expirer.

Q2) Допустим, если Map вызывается только потоком, тогда нам когда-нибудь понадобится блокировка повторного входа в ExpiringObject. Поскольку setLastAccessTime вызывается только потоком при вызове метода put Map, а метод getLastAccessTime будет вызываться потоком Expirer. Причина, по которой я спрашиваю, заключается в том, что я протестировал вставку объектов размером 1M, Reentrant Lock занимает более 100 МБ

2 ответа

Решение

Блокировка необходима, поскольку длинное значение не может быть обновлено атомарно в 32-битных системах.

Альтернативы:

  • Замените длинный на длинный. Ссылка обновлена ​​атомарно.

  • Используйте AtomicLong

  • Продолжайте использовать объект Lock, но используйте статический массив блокировок размером примерно с двойным числом доступных процессоров и индексируйте его с помощью блокировок [hashCode() % locks.length]

И последний вариант: используйте кеш, который уже оптимизирован, например, EHCache, Google Guava или cache2k.

Чтобы ответить на ваш вопрос, я не совсем уверен, почему lastAccessTimeLock потребует блокировки, поскольку изменения в ней не должны совпадать с изменениями чего-либо еще (атомарно). ИМО, замок не нужен. Вы хотели бы убедиться, что изменения в lastAccessTimeLock видны другим потокам, хотя, что можно сделать, пометив его как volatile или используя AtomicLong,

Что касается вашей проблемы использования памяти, вы можете проверить эту библиотеку ExpiringMap, а не использовать реализацию Mina.

Другие вопросы по тегам