如何使用spymemcached实现原子操作“setIfAbsent”

时间:2014-04-21 05:28:26

标签: java memcached spymemcached

我使用Memcached(使用spymemcached作为客户端)来缓存从远程服务器收到的响应。我的程序的逻辑很简单:

  • 如果请求的资源缓存在Memcached中,则立即返回缓存;
  • 如果没有,请连接到远程服务器,对其进行缓存,然后返回结果。

程序类似于

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并发工具来实现这一点。)

1 个答案:

答案 0 :(得分:1)

memcached中有add命令可以执行您想要的操作(list of commands)。为了避免调用两次或更多次getTheResourceFromTheRemoteServer,您应该使用memcached(adddelete命令的组合)来模拟写锁。因此,只有在同一个特定键(RESOURCE_KEY_LOCK)上成功调用add的线程才应调用getTheResourceFromTheRemoteServer并将其置于缓存中。其他线程应该等待并再次调用get(RESOURCE_KEY)