高并发中的atomic

CAS原理

对于并发控制而言,锁是一种悲观策略,会阻塞线程执行。而无锁是一种乐观策略,它会假设对资源的访问时没有冲突的,既然没有冲突就不需要等待,线程不需要阻塞

CAS方法包含三个参数CAS(V,E,N):
内存位置(V),预期原值(A)和新值(B)。
如果内存位置的值与预期原值相匹配,那么处理器将会自动将该位置值更新为新值,否则,不做任何操作。
如果V的值不等于E,说明已经被其他线程修改了,当前线程可以放弃此操作,也可以再次尝试次操作直至修改成功。

public final int getAndSet(int newValue) {
    for (;;) {
        int current = get();
        if (compareAndSet(current, newValue))
            return 
public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

在AtomicInteger的源码中,可以看到compareAndSet只有预期和更新两个入参,而该类的成员value被加上了Volatile关键字

Unsafe类是CAS实现的核心。

现在的CPU都支持“读-比较-修改”的原子操作,也就是一个cpu在执行这个操作的时候,绝对不会被其他线程中断。在多CPU的情况下,volatile保证了线程可以及时发现临界区的修改。


Atomic包:
假如想实现一个功能来统计网页访问量,可以用count++ 来统计访问量,但是这个自增操作不是线程安全的。

count++ 可以分成三个操作:

  1. 获取变量当前值
  2. 给获取的当前变量值+1
  3. 写回新的值到变量
  • 并发中的问题
    假如count的值目前是10,线程A和线程B都进行了操作1,即取到了count=10的值,
    接下来同时进行操作2,
    但是A先进行到操作3,count现在值为11。
    但是因为B一开始取出的count的值也是10,所以B执行到操作3后,count的值依然是11。

在java.util.concurrent包下可以使用AtomicInteger来保证线程安全。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 11,319评论 4 56
  • 第2章 java并发机制的底层实现原理 Java中所使用的并发机制依赖于JVM的实现和CPU的指令。 2.1 vo...
    kennethan阅读 1,461评论 0 2
  • 除了春节,就是中秋了 有时间有条件 一般回到老家乡下 和父母团聚,和亲人们团聚,这么多年 我欠父亲几句话 祝他生日...
    张自芳阅读 325评论 0 3
  • 项目起源于需要查看商品编辑版本之间的不同并标注; 另外正好在学习Python的爬虫程序,目前已经学会获取网页的标签...
    一念佛魔分阅读 294评论 1 0
  • 日常生活里,我们每天都要面临五花八门的新鲜事物,但物品的增多,反而促使一种新的生活方式开始盛行,那就是极简主义。 ...
    脱俗儿阅读 643评论 0 0