Browsed by
标签: cas

从LongAdder看更高效的无锁实现

从LongAdder看更高效的无锁实现

(感谢 @jd刘锟洋 投稿,更多文章参看他的博客:码梦为生

原文链接:《比AtomicLong还高效的LongAdder 源码解析

接触到AtomicLong的原因是在看guava的LoadingCache相关代码时,关于LoadingCache,其实思路也非常简单清晰:用模板模式解决了缓存不命中时获取数据的逻辑,这个思路我早前也正好在项目中使用到。

言归正传,为什么说LongAdder引起了我的注意,原因有二:

  1. 作者是Doug lea ,地位实在举足轻重。
  2. 他说这个比AtomicLong高效。

我们知道,AtomicLong已经是非常好的解决方案了,涉及并发的地方都是使用CAS操作,在硬件层次上去做 compare and set操作。效率非常高。

因此,我决定研究下,为什么LongAdder比AtomicLong高效。

首先,看LongAdder的继承树:

la1

继承自Striped64,这个类包装了一些很重要的内部类和操作。稍候会看到。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (26 人打了分,平均分: 3.88 )
Loading...
多版本并发控制(MVCC)在分布式系统中的应用

多版本并发控制(MVCC)在分布式系统中的应用

感谢 Todd投递本文 – 微博帐号:weidagang

问题

最近项目中遇到了一个分布式系统的并发控制问题。该问题可以抽象为:某分布式系统由一个数据中心D和若干业务处理中心L1,L2 … Ln组成;D本质上是一个key-value存储,它对外提供基于HTTP协议的CRUD操作接口。L的业务逻辑可以抽象为下面3个步骤:

  1. read: 根据keySet {k1, … kn}从D获取keyValueSet {k1:v1, … kn:vn}
  2. do: 根据keyValueSet进行业务处理,得到需要更新的数据集keyValueSet’ {k1′:v1′, … km’:vm’} (:读取的keySet和更新的keySet’可能不同)
  3. update: 把keyValueSet’更新到D (:D保证在一次调用更新多个key的原子性)

在没有事务支持的情况下,多个L进行并发处理可能会导致数据一致性问题。比如,考虑L1和L2的如下执行顺序:

  1. L1从D读取key:123对应的值100
  2. L2从D读取key:123对应的100
  3. L1将key:123更新为100 + 1
  4. L2将key:123更新为100 + 2

如果L1和L2串行执行,key:123对应的值将为103,但上面并发执行中L1的执行效果完全被L2所覆盖,实际key:123所对应的值变成了102。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (26 人打了分,平均分: 3.46 )
Loading...