CASMutator/CASMutation捕捉最佳实践和工作流程,以便为您完成正确的事情。
你的反例看起来更简单,因为你不说的话,你会真正做与方法。您上面发布的示例显示了一个正在从Memcached中取出的List,添加了一个新项目,有条件地从中删除一些项目,然后将其重新放回。您发布的文本中至少有一半仍需要编写。
如果您不是请使用 CASMutator,您最终将重新发明它,这并非如此简单。这就是它为你今天做的:
public T cas(final String key, final T initial, int initialExp,
final CASMutation<T> m) throws Exception {
T rv=initial;
boolean done=false;
for(int i=0; !done && i<max; i++) {
CASValue<T> casval=client.gets(key, transcoder);
T current=null;
// If there were a CAS value, check to see if it's compatible.
if(casval != null) {
T tmp = casval.getValue();
current=tmp;
}
// If we have anything mutate and CAS, else add.
if(current != null) {
// Declaring this impossible since the only way current can
// be non-null is if casval was set.
assert casval != null : "casval was null with a current value";
rv=m.getNewValue(current);
// There are three possibilities here:
// 1) It worked and we're done.
// 2) It collided and we need to reload and try again.
// 3) It disappeared between our fetch and our cas.
// We're ignoring #3 because it's *extremely* unlikely and the
// behavior will be fine in this code -- we'll do another gets
// and follow it up with either an add or another cas depending
// on whether it exists the next time.
if(client.cas(key, casval.getCas(), rv, transcoder)
== CASResponse.OK) {
done=true;
}
} else {
// No value found, try an add.
if(initial == null) {
done = true;
rv = null;
} else if(client.add(key, initialExp, initial, transcoder).get()) {
done=true;
rv=initial;
}
}
}
if(!done) {
throw new RuntimeException("Couldn't get a CAS in " + max
+ " attempts");
}
return rv;
}
好吧,你是完全正确的,但你不觉得这个解决方案是相当侵入? – terry 2011-06-15 20:22:19
侵入什么方式?它是在CAS处理器上对处理器进行建模之后建立的,除了在单个关键高竞争位置之外,它应该可以很好地扩展。老实说,Java使它变得更加困难。大多数代码只是一个简单的lambda表达式,在许多语言中。 Java只是带来了一堆语法来包装它。 – Dustin 2011-06-15 21:38:59
在我看来,因为我必须把我的业务代码放在spymemcached getNewValue函数定义中。你不觉得使用一些图案或分离层是不可能的吗? – terry 2011-06-16 21:25:01