如果对concurrentmap接口比较熟悉的话,这个其实是一个比较简单的问题。在concurrentmap中最主要的就是引入几个cas相关的操作:
public interface concurrentmap<k, v> extends map<k, v> {
v putifabsent(k key, v value);
boolean remove(object key, object value);
boolean replace(k key, v oldvalue, v newvalue);
v replace(k key, v value);
}
/**
* replaces the entry for a key only if currently mapped to a given value.
* this is equivalent to
* <pre>
* if (map.containskey(key) &amp;&amp; map.get(key).equals(oldvalue)) {
* map.put(key, newvalue);
* return true;
* } else return false;</pre>
* except that the action is performed atomically.
*
* @param key key with which the specified value is associated
* @param oldvalue value expected to be associated with the specified key
* @param newvalue value to be associated with the specified key
* @return <tt>true</tt> if the value was replaced
* @throws unsupportedoperationexception if the <tt>put</tt> operation
* is not supported by this map
* @throws classcastexception if the class of a specified key or value
* prevents it from being stored in this map
* @throws nullpointerexception if a specified key or value is null,
* and this map does not permit null keys or values
* @throws illegalargumentexception if some property of a specified key
* or value prevents it from being stored in this map
*/
在concurrentmap的value中我们只需要给integer,然后用replace去不断的尝试,即自己实现一个cas:
private int incrementrefcount(object key) {
do {
integer curcount = distributedmap.get(key);
if (curcount == null) {
curcount = distributedmap.putifabsent(key, new integer(1));
if (curcount == null) {
return 1;
}
}
integer newcount = new integer(curcount.intvalue() + 1);
if (distributedmap.replace(key, curcount, newcount)) {
return newcount;
} while (true);
主要逻辑就是这样了,其实比较简单,只是之前没有遇到过这个问题,所以感觉可以记录下来。或许什么时候补充一下zookeeper版本的实现。