java - ConcurrentHashMap 移除键
问题描述
我试图弄清楚如何编写一个线程安全的、过期的条目、缓存。这个缓存会用作no-hits
缓存,这样如果某个存储在某个存储中没有找到条目,我会将它放入这个缓存中,避免接下来几分钟的后续调用。
将有多个线程读取和写入此缓存。
我的应用程序中只有一个 ThreadSafeCache 实例。
我不确定删除 contains 方法中的条目是否会出现同步问题。
我如何测试这个类的线程安全性?
亲切的问候
public class ThreadSafeCache
{
private final Clock clock = Clock.systemUTC();
private final Duration expiration = Duration.ofMinutes(10);
private final ConcurrentHashMap<CacheKey, CacheValue> internalMap = new ConcurrentHashMap<>();
public boolean contains(String a, String b, byte[] c, String d)
{
CacheKey key = new CacheKey(a, b, c, d);
CacheValue value = internalMap.get(key);
if (value == null || value.isExpired())
{
internalMap.remove(key);
return false;
}
return true;
}
public void put(String a, String b, byte[] c, String d)
{
internalMap.computeIfAbsent(new CacheKey(a, b, c, d), key -> new CacheValue());
}
private class CacheValue
{
private final Instant insertionDate;
private CacheValue()
{
this.insertionDate = clock.instant();
}
boolean isExpired()
{
return Duration.between(insertionDate,
clock.instant()).compareTo(expiration) > 0;
}
}
}
解决方案
您在同一个函数中调用 2 个 Map 操作,这意味着存在交错的范围(即另一个操作发生在函数的 2 个操作之间,从而改变了它的行为)。要解决此问题,您可以将地图操作放在一个synchronized (internalMap) {}
块中。请注意,您必须对在 2 个离散方法调用中与地图交互的任何方法执行此操作。
从代码风格的角度来看,在contains
方法中修改映射是不好的做法。这将使您的代码难以预测。第一次访问您的代码的其他人(或几个月后的您)可能不记得contains()
实际修改了缓存。contains
意味着它只是检查缓存,而不是修改它。
我的建议是:
- 如果密钥已过期,只需返回 false。
- 在该
get()
方法中,检查该值是否已过期,如果已过期,则在那里计算一个新值。
推荐阅读
- python - 如何撤消 jupyter notebook 的 cmd 命令?
- python - I can iterate through my first iteration of PyTorch successfully, but am unable to do a second iteration. Please see code and error I get
- google-sheets - Gsheets replacing value of cell based on another cell
- java - How can I map one class to another in spring boot w/ neo4j?
- kotlin - What is the programming term for reducing hidden complexity associated with temporal/implicit coupling?
- javascript - Using react hooks and google maps api How to show one directions with waypoints and single different marker on same map?
- c - May an implementation optimize an atomic access to a non-atomic access, if it happens through a restrict pointer?
- javascript - I'm not able to install gatsby-plugin-transition-link with npm
- php - Attach PHP fputcsv as PHPMailer attachment
- php - imap_open authentication failure on localhost