美文网首页
高并发中的atomic

高并发中的atomic

作者: Tommmmm | 来源:发表于2018-11-17 21:48 被阅读0次

    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来保证线程安全。

    相关文章

      网友评论

          本文标题:高并发中的atomic

          本文链接:https://www.haomeiwen.com/subject/ytsatqtx.html