Java 如何同步访问ehcache、memcached&;其他键值存储?

Java 如何同步访问ehcache、memcached&;其他键值存储?,java,concurrency,memcached,couchdb,ehcache,Java,Concurrency,Memcached,Couchdb,Ehcache,根据我的理解,get()和put()这两种方法都是原子的 但是,当以CheckThenAct的方式访问ehcache&memcached等缓存时,会出现竞争条件 我们应该同步什么,以确保如果thread1执行Get(),thread2执行Get(),然后执行Put(),那么第一个Get()将接收由thread2?添加的新值处理这种情况的方法是不缓存来自多个位置的写入或以其他方式控制访问 一个简单的解决方案是不从客户端向缓存写入任何内容。相反,如果要更新该值,则会发出更新该值的请求。如果该值是从其

根据我的理解,
get()
put()
这两种方法都是原子的

但是,当以
CheckThenAct
的方式访问ehcache&memcached等缓存时,会出现竞争条件


我们应该同步什么,以确保如果thread1执行
Get()
,thread2执行
Get()
,然后执行
Put()
,那么第一个
Get()
将接收由
thread2

添加的新值处理这种情况的方法是不缓存来自多个位置的写入或以其他方式控制访问

一个简单的解决方案是不从客户端向缓存写入任何内容。相反,如果要更新该值,则会发出更新该值的请求。如果该值是从其他地方检索到的,那么这可以很好地工作。如果它是计算出来的,或者来自客户机,那么问题可能会更大

至少在PHP世界中,与memcache一起使用的一个常见组件是beanstalkd,它是一个分布式工作队列处理器。在这个场景中,您可以将“更新缓存”请求作为一个工作单元发出

如果在缓存项上执行的操作使用现有值作为输入,或者如果get-then-update不是原子操作,则会以其他方式引入竞争条件,另一种方法是创建一个包含旧值和新值的工作单元。这样,处理更新的任何进程都可以使当前值不是预期值的情况无效或以其他方式处理这些情况


递增和递减由memcached接口处理,因此,如果您的访问属于该类型(或者可以减少为该类型的操作),那么这也解决了问题。

对于memcached,您可以利用cas()操作在执行put()之前进行检查另一个操作没有更新数据。

我可能能够重新构造逻辑以使用原子incr()和decr()操作。但并不是每个应用程序都会一直属于这一类。即使使用递增和递减,您在设置初始值时也会遇到问题。如果该值不是整数,则增量将不起任何作用。如果您想要精确的值,您需要预先填充要递增的值。@Miha说得好!在数据库世界中,我也做同样的事情,预先填充表,这样我就可以对它们进行行锁定。好的,您不能在不存在的行上锁定行。不幸的是,EhCache似乎没有类似的功能:-/