天天看点

分布式Map中实现引用计数前言实现

如果对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) && 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版本的实现。