zoukankan      html  css  js  c++  java
  • LongAccumulator 源码分析

    LongAccumulator

    LongAccumulator 能解决什么问题?什么时候使用 LongAccumulator?

    1)LongAccumulator 的逻辑和 LongAdder 基本类似,唯一不同的是 LongAccumulator
    持有一个函数式接口,目标值是通过该接口计算得到的,相对于 LongAdder,LongAccumulator 更灵活。
    

    如何使用 LongAccumulator?

    1)多线程并发更新一个统计值时可以采用 LongAccumulator,如最高同时在线人数。
    

    使用 LongAccumulator 有什么风险?

    1)LongAccumulator 使用空间换时间的模式会消耗更多的内存
    

    LongAccumulator 核心操作的实现原理?

    创建实例

        /**
         * 二元函数式接口
         */
        private final LongBinaryOperator function;
        /**
         * 身份值
         */
        private final long identity;
    
        /**
         * 基于一个二元函数式接口和身份值创建 LongAccumulator 实例
         */
        public LongAccumulator(LongBinaryOperator accumulatorFunction,
                long identity) {
            function = accumulatorFunction;
            base = this.identity = identity;
        }
    

    更新值

        /**
         * 使用指定的值 x 更新 LongAccumulator
         */
        public void accumulate(long x) {
            Cell[] cs; long b, v, r; int m; Cell c;
            /**
             * 1)cells 为 null &&
             * 使用函数式接口基于 base 和目标值 x 计算新值不等于 b &&
             * 尝试原子更新 base
             * 2)cells 不为 null
             */
            if ((cs = cells) != null
                    || (r = function.applyAsLong(b = base, x)) != b
                    && !casBase(b, r)) {
                /**
                 * 1)原子更新失败
                 * 2)cells 不为 null
                 */
                boolean uncontended = true;
                /**
                 * 1)cells 为 null,则执行初始化
                 * 2)通过线程探测值定位的 cell 为 null,则尝试直接写入值
                 * 3)基于 cell 值和目标值 x 计算后的值和旧值不相等 && 原子更新失败,
                 * 说明出现 cell 竞争,则需要重新计算并写入值。
                 */
                if (cs == null
                        || (m = cs.length - 1) < 0
                        || (c = cs[Striped64.getProbe() & m]) == null
                        || !(uncontended =
                        (r = function.applyAsLong(v = c.value, x)) == v
                        || c.cas(v, r))) {
                    longAccumulate(x, function, uncontended);
                }
            }
        }
    

    读取值

        /**
         * 根据函数式接口循环计算新值【参数为累计值和当前 Cell 中的旧值】并返回最终值,
         * 如果计算过程中未发生竞争,则该值是精确的。
         */
        public long get() {
            final Cell[] cs = cells;
            long result = base;
            if (cs != null) {
                for (final Cell c : cs) {
                    if (c != null) {
                        result = function.applyAsLong(result, c.value);
                    }
                }
            }
            return result;
        }
    
  • 相关阅读:
    MVC模式-----struts2框架(2)
    MVC模式-----struts2框架
    html的<h>标签
    jsp脚本元素
    LeetCode "Paint House"
    LeetCode "Longest Substring with At Most Two Distinct Characters"
    LeetCode "Graph Valid Tree"
    LeetCode "Shortest Word Distance"
    LeetCode "Verify Preorder Sequence in Binary Search Tree"
    LeetCode "Binary Tree Upside Down"
  • 原文地址:https://www.cnblogs.com/zhuxudong/p/10055558.html
Copyright © 2011-2022 走看看