2017-06-01 122 views
1

我正在使用Hazelcast(JCache标准)编写分布式应用程序进行缓存。锁定榛树群集中的密钥

我有一个用例,我应该锁定群集中的特定键以防止在更新期间调用。

  1. 线程1:得到物品1的配置变化(把锁)
  2. 线程2:获得物品1的更新。
  3. thread2:将item1更新并添加一个新的时间戳。
  4. 线程1:把物品1用一个旧值和时间戳

我知道了Ehcache具有非常相似的,这就是所谓的acquireReadLockOnKey(对象键)的东西。

如何使用JCache和/或Hazelcast实现这种锁定?

回答

2

查看Entry Processor,它以原子和无锁方式对缓存条目执行更新操作。

+0

正在谈论从JCache的EntryProcessor?它是否在分布式缓存中正常工作? – Forin

+2

在我们的项目中,我们使用Hazelcast IMap的入门处理器,并且我们没有遇到并发问题。入门处理器是改变分布式环境中数据的好方法。输入处理器在密钥所有者上执行,它允许实现原子性 并避免通过网络发送数据。 –

+0

这两个答案都有优点;如果您的争用率较低,则可以按照上述说明去CAS。否则,您可以使用JCache'EntryProcessor',[其合约](https://github.com/jsr107/jsr107spec/blob/37937a43c66b986dbfc0aa8291c8f10975b26dc0/src/main/java/javax/cache/processor/EntryProcessor.java#L26-L32)保证它将以原子方式在一个键上执行。您只需确保您的'EntryProcessor'代码部署在Hazelcast集群的所有成员上。 –

3

我会建议使用CAS(比较和设置)类似的操作(如ConcurrentMap :: replace),并利用本身不是真正的锁的乐观锁定模式。

while(true) { 
    // Get the old value 
    T oldValue = map.get(key); 
    // Create the new value based on the "known old state" 
    T newValue = createNewValue(oldValue); 
    // Try to atomically exchange to the new value, if oldValue is still valid 
    if (map.replace(key, oldValue, newValue) break; 
    // If oldValue isn't valid anymore, retry 
} 

在没有高争用率的大多数情况下,这是真正锁定的最佳替代方案。它解决了大部分读 - 修改 - 写问题,并且不需要在集群上部署/使用EntryProcessor类。

相关问题