天天看點

分布式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版本的實作。