我使用Memcached(使用spymemcached作为客户端)来缓存从远程服务器收到的响应。我的程序的逻辑很简单:
程序类似于
Object cachedResource = spyMemcachedClient.get(RESOURCE_KEY);
if (cachedResource != null) {
return cachedResource;
} else {
Object remoteResource = getTheResourceFromTheRemoteServer();
spyMemcachedClient.set(RESOURCE_KEY, EXP_TIME, remoteResource);
return remoteResource;
}
但是我注意到,由于同时会有很多并发请求,因此两个线程都可能cachedResource
找到null
,因此它们都会调用getTheResourceFromTheRemoteServer
,我不想。
那么,我该怎样避免这种情况。在spymemcached中是否有像ConcurrentMap.putIfAbsent
这样的原子操作。 (顺便说一句,程序将部署在多个实例上,这意味着不可能使用像Lock这样的Java并发工具来实现这一点。)
答案 0 :(得分:1)
memcached中有add
命令可以执行您想要的操作(list of commands)。为了避免调用两次或更多次getTheResourceFromTheRemoteServer
,您应该使用memcached(add
和delete
命令的组合)来模拟写锁。因此,只有在同一个特定键(RESOURCE_KEY_LOCK)上成功调用add
的线程才应调用getTheResourceFromTheRemoteServer
并将其置于缓存中。其他线程应该等待并再次调用get(RESOURCE_KEY)