Кешировние -- штука не простая. Я тож попадал на race condition, когда пытался читать кэш, а он пустой -- перестраивается.
Вариант, который предлагает Сергей, может быть выходом. Но тут есть один недостаток -- никак не ограничен объем памяти, который занимает кэш. Кэш может отъесть сколько угодно памяти, и держать невостребованные данные сколько угодно долго. Это подходит, если заранее известно, что все данные, которые попадают или потенциально могут попасть в кеш, занимают известный объем памяти, и не будут бесконтрольно расти.
Другие варианты кэша подразумевают установленный лимит памяти, и активное вытеснение невостребованных данных. Для этого нужно делать регулярные проходы по таблице с удалением.