2014-04-21 25 views
1

我使用的Memcached(使用spymemcached作为客户机)来缓存从远程服务器接收到的响应。我的程序逻辑很简单:如何实现一个原子操作“setIfAbsent”使用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; 
} 

但我注意到,自会有在同一时间许多并发请求,有可能两个线程都找到cachedResourcenull,所以他们都调用getTheResourceFromTheRemoteServer,我不想。

所以,我怎样才能避免这种情况。在spymemcached中是否有像ConcurrentMap.putIfAbsent这样的原子操作? (顺便说一句,该程序将部署在多个实例上,这意味着不可能使用像Lock这样的Java并发实用程序来实现这一点。)

回答

1

在你想要的memcached中有add命令(list of commands )。为避免调用两次或更多次getTheResourceFromTheRemoteServer您应该使用memcached(adddelete命令的组合)来模拟写入锁定。因此,只有在相同特定密钥(RESOURCE_KEY_LOCK)上成功调用add的线程应该调用getTheResourceFromTheRemoteServer并将其放入缓存中。其他线程应该等待并再次调用get(RESOURCE_KEY)