首页 > 其他分享 >JUC系列之(三)原子变量

JUC系列之(三)原子变量

时间:2024-02-29 19:35:39浏览次数:31  
标签:JUC 变量 ++ 原子 CAS AtomicDemo public

原子变量-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());
    }
}

标签:JUC,变量,++,原子,CAS,AtomicDemo,public
From: https://www.cnblogs.com/wzzzj/p/18045236

相关文章

  • JUC系列之(二)volatile关键字
    volatile关键字-内存可见性引出内存可见性问题的示例:packagecom.atguigu.juc;publicclassTestVolatile{publicstaticvoidmain(String[]args){//线程threadDemo修改共享变量的值ThreadDemothreadDemo=newThreadDemo();newThrea......
  • Path环境变量
    1.为什么要配置Path环境变量?方便在命令行中启动程序。2.什么是Path环境变量?(path路径) 3.如何配置?     注意不能删除原来的路径......
  • 变量重复定义声明会怎样??
    在同一个作用域内重复定义一个变量通常会报错。如:#include<stdio.h>intglobal_var=10;//第一次定义全局变量intmain(){intglobal_var=20;//第二次定义全局变量并赋予不同的值printf("Globalvariable:%d\n",global_var);return0;}在不同作......
  • JAVA基础:数组在计算机中的执行原理 多个变量指向一个数组
    程序都是在计算机中的内存中执行的,java程序编译之后会产生一个class文件,这个class文件是提取到内存中的JVM虚拟机中执行的。java为了便于虚拟机这个java程序,也即这个class文件。将虚拟机这块内存区域进行了划分:方法区,栈,堆,  本地方法栈,程序计数器方法区:放编译后的class文件的......
  • postman 设置全局变量
    目的:如下图,需要把接口返回的data字段内容在下一个接口引用。代码:varjsondate=pm.response.json();//拿到接口返回的全部内容vardata=jsondate.data;//把接口返回内容中需要提取的值赋值给一个参数console.log(data);//可以通过输出到控制台查看是否提取成功;pm......
  • mysql和oracle执行sql时弹出变量输入框
    MySQL查询条件中实现弹窗输入变量这种属于客户端软件自身的交互,是由客户端自身实现的特性,所以不同客户端的实现方式也不一样,大致列几个常用客户端的SQL语句实现方式如下:PL/SQL:使用&引用变量弹框输入变量值wherePeriod_Start_Time>=to_date(&开始时间,'yyyymmddhh24')andPeriod_S......
  • 类变量在高并发环境下引发的线程安全问题
    ###背景生产环境中,登录接口出现偶发性的异常,排查发现是获取当前时间的工具类抛出异常,以下为代码片段:``````java/***时间工具类*/publicclassDateUtil{ Loggerlogger=LoggerFactory.getLogger(this.getClass());privatefinalstaticSimpleDateFormatshortSdf=new......
  • STEP: 用于多变量时间序列预测的预训练增强时空图神经网络《Pre-training Enhanced Sp
    2023年12月27日,看一篇老师给的论文。论文:Pre-trainingEnhancedSpatial-temporalGraphNeuralNetworkforMultivariateTimeSeriesForecasting或者是:Pre-trainingEnhancedSpatial-temporalGraphNeuralNetworkforMultivariateTimeSeriesForecastingGitHub:https:......
  • Java 基础变量
    基本数据类型:字符型:char,数字类型:整数型:Byte,short,int,long(long 类型的数据一定要在数值后面加上 L,否则将作为整型解析)         浮点型:float,double布尔型:boolean引用类型:String定义变量,变量作用域包装类型:八种基本类型都有对应的包装类分别为:Byte、Sh......
  • 【译】代码更快、更好,借助 GitHub Copilot 的新功能:斜杠命令和上下文变量
    你是否曾经希望有一个人工智能助手可以帮助你更快更好地编写代码?那就是VisualStudioCopilotChat为您提供的:一个人工智能驱动的结对程序员,可以回答您的问题,建议代码片段,解释代码逻辑,并与您讨论您的项目。您可以使用Copilot更快更好地编写代码,因为它可以帮助您避免错误并......