JUC系列之(三)原子变量

原子变量-CAS算法

1. i++的原子性问题

i++的计算原理:读 - 改 - 写

int temp = i;
i = i + 1;

将i++赋给其他变量的时候会将temp的值赋给其他变量,比如:
int i = 10;
i = i++;  // 这里i的值就是10,i++的值实际上就是临时变量temp的值

i++的原子性问题实例

package com.atguigu.juc;

public class TestAtomicDemo {
    public static void main(String[] args) {
        AtomicDemo atomicDemo = new AtomicDemo();

        for(int j = 0; j< 20 ;j++){
            new Thread(atomicDemo).start();
        }
    }
}

class AtomicDemo implements Runnable{
    private int i = 0;

    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
        }
        System.out.println(i++);
    }
}

分析过程如下

2. 原子变量

jdk1.5后java.util.concurrent.atomic包下提供了常用的原子变量

工作原理:

  1. volatile保证内存可见性

  2. CAS (Compare-And-Swap)算法保证数据的原子性

    CAS算法是硬件对于并发操作共享数据的支持CAS包含了三个操作数:
    内存值 V
    预估值(旧值) A

    更新值(新值) B
    当且仅当V == A时, 才将B的值更新到共享变量中。否则,将不做任何操作

CAS算法逻辑:读取内存值作为V,计算出新值B后在替换之前再次读取内存值作为预估值A,比较内存值V和预估值A,如果相等则进行替换(比较并替换这个步骤是原子操作)

CAS算法:无锁、非阻塞

1.读取内存值

2.比较并交换

CAS算法与同步锁的比较:

CAS算法效率要高于同步锁,因为替换失败时不会阻塞,会一直重复进行

用原子变量改写3.1中的示例,解决i++的原子性问题

package com.atguigu.juc;

import java.util.concurrent.atomic.AtomicInteger;

public class TestAtomicDemo {
    public static void main(String[] args) {
        AtomicDemo atomicDemo = new AtomicDemo();

        for(int j = 0; j< 20 ;j++){
            new Thread(atomicDemo).start();
        }
    }
}

class AtomicDemo implements Runnable{
//    private volatile int i = 0;
    private AtomicInteger i = new AtomicInteger(0);

    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
        }
        System.out.println(i.getAndIncrement());
    }
}
posted @   刘二水  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示