LongAddr全局序列号不准确的问题

来源:16-1 数据库切库分库分表思路

ymvkujn

2019-01-12

LongAddr这个地方反复听了几遍,不是很明白,LongAddr在高并发下,将锁分散到每个拆分后的cells! 减少自旋! 那是不是意味着会有多个线程同时拿到锁后调用LongAddr的sum()方法去做累加? 而这个全局序列号不准确是因为sum()方法中对cell做累加并不是原子操作导致的(虽然base值修改能做到可见)!不知道我的理解对不对?请老师指教

写回答

1回答

Jimin

2019-01-13

你好,这个拿核心代码讲解一下,重点看对这段核心的注释。

// 返回累加的和,也就是“当前时刻”的计数值



 // 此返回值可能不是绝对准确的,因为调用这个方法时还有其他线程可能正在进行计数累加,



 // 方法的返回时刻和调用时刻不是同一个点,在有并发的情况下,这个值只是近似准确的计数值



 // 高并发时,除非全局加锁,否则得不到程序运行中某个时刻绝对准确的值,但是全局加锁在高并发情况下是下下策



 // 在很多的并发场景中,计数操作并不是核心,这种情况下允许计数器的值出现一点偏差,此时可以使用LongAdder



 // 在必须依赖准确计数值的场景中,应该自己处理而不是使用通用的类



 public long sum() {



     Cell[] as = cells; Cell a;



     long sum = base;



     if (as != null) {



         for (int i = 0; i < as.length; ++i) {



             if ((a = as[i]) != null)



                 sum += a.value;



         }



     }    



     return sum;



 }

这里说的不准确,是因为在返回值的过程中可能还有其他线程在操作,但是如果是明确的指定次操作,这些操作之后最终的结果是正确的

1
1
ymvkujn
非常感谢!
2019-01-13
共1条回复

Java高并发编程,构建并发知识体系,提升面试成功率

构建完整并发与高并发知识体系,倍增高薪面试成功率!

3923 学习 · 832 问题

查看课程