2014-04-21 26 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)