很早之前在公司就看到了atomicInteger,atomicLong这些变量了,一直不明白是什么意思,今天花了点时间了解下。

volatile:

先从volatile开始讲起,volatile是多线程中会使用的关键字,volatile不加锁(即不会线程阻塞,但不安全),但保证了可见性(一个线程修改,立即刷新到主内存,对其他线程可见)和禁止指令重排序。但是这样依然对存在一个问题,就是多线程时候来不及刷新到主内存中,新线程就获取到了旧数据。例如下面代码:

错误原因:有的线程已经把a进行了加1操作,但是还没来得及重新刷入到主存,其他的线程就重新读取了旧值。因为才造成了错误

package atomic;

import java.util.concurrent.atomic.AtomicInteger;

/**
* @ProjectName: AtomicIntegerTest
* @Package: atomic
* @Description:
* @Author: huyuqiao
* @CreateDate: 2020/9/21 14:25
*/
//Volatile:无法保证最后a结果一定是50
//AtomicInteger:虽然最后顺序不一样,但是最终a一定是50
public class AtomicIntegerTest {
// private static volatile int a = 0;
static AtomicInteger a = new AtomicInteger();
public static void main(String[] args){
AtomicIntegerTest atomicIntegerTest = new AtomicIntegerTest();
Thread[] threads = new Thread[5];
for (int i = 0; i < 5; i++) {
threads[i] = new Thread(() ->{
try{
for (int i1 = 0; i1 < 10; i1++) {
// System.out.println(a++);
System.out.println(a.incrementAndGet());
Thread.sleep(500);
}
} catch (Exception e){
e.printStackTrace();
}
});
threads[i].start();
}
}
}
atomicInteger

上面代码中atomicInteger却保证了数据的完整性,原因就在于内部CAS原理(compare and swap)

CAS 即比较并替换,实现并发算法时常用到的一种技术。CAS操作包含三个操作数——内存位置、预期原值及新值。执行CAS操作的时候,将内存位置的值与预期原值比较,如果相匹配,那么处理器会自动将该位置值更新为新值,否则,处理器不做任何操作。

但是这样会有一个ABA问题,就是虽然你保证了数据最终一定一直,但是无法保证数据中途会被修改,即ABA问题(变量A->B->A中途会被修改)

ABA问题解决办法:解决使用AtomicStampReference.getstamp标记更新次数,若没被更新,则正确,否则报错。

面试问题:并发编程(原子性、可见性、一致性)

Java-学习日记(Atomic,Volatile)的更多相关文章

  1. [转]Java学习日记之 volatile

    用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来 ...

  2. Java学习日记-2 零零碎碎

    一.使用Scanner类进行控制台的输入 文档中Scanner类的定义为A simple text scanner which can parse primitive types and string ...

  3. Java学习日记基础篇(六)—— 抽象类、接口、final

    抽象类 为什么要有抽象类? 因为父类方法有不确定性,我们在Animal中定义了一个方法,但是它会被子类的方法覆盖掉,我们就不知道这个方法原本是做什么的 public class test1 { pub ...

  4. Java学习日记基础(五)——类、对象之this、静态变量(类变量)、静态方法(类方法)、四大特征

    this 赵本山问奥尼尔:“我的爸爸的爸爸是谁?” 奥尼尔:“不知道” 赵本山:“你傻啊,是我爷爷” 奥尼尔回去问科比:“我的爸爸的爸爸是谁?” 科比:“不知道” 奥尼尔:”你傻啊,是赵本山的爷爷“ ...

  5. Java学习日记基础篇(四)——类,对象之成员变量,成员方法,构造方法

    面向对象(Object Oriented) 一.面向对象杂谈 面向对象(Object Oriented),我的翻译是以物体为目标的,就是说编程的时候是建立一个物体,然后对这个物体进行操作. Java语 ...

  6. Java学习日记——基础篇(二)基本语法

    变量 变量和常量是程序处理的两种基本数据对象,变量是程序的基本组成单位 变量的目的就是确定目标并提供存放空间 public class Hello { public static void main( ...

  7. Java学习日记之 Java-其他类型

    OK , 就绪, 第一篇博客开撸 ~ 先听了毕姥爷激情澎湃的其他类型 ,从这里开始入手吧 : (一)System类  System类代表系统类,系统的属性和方法都放在该类.System类是一个fina ...

  8. Java学习日记之 Java-IO流

    Java中的IO流在处理上分为字节流和字符流.字节流和字符流的区别 : 1.字节流读取的时候,读到一个字节就返回一个字节:  字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8 ...

  9. Java学习日记-10 集合

    集合(Collection) 1. 什么是集合? 集合是一组对象组成的一个整体,又称为容器,集合类属于java.util包.集合不同于数组的地方在于,一是它的容量是可变的,二是集合中只能存储对象,不能 ...

随机推荐

  1. JS数组的操作方法汇总

    数组的增删 push():添加到最后 pop():取出最后一个 shift():取出第一个 unshift():添加到第一个 splice() : 返回删除的数组,如果没有则为空数组,会改变原数组.可 ...

  2. 安装过程中出现一个错误: No such plugin: cloudbees-folder

    上面的错误显示是,安装插件cloudbees-folder失败,是因为下载的Jenkins.war里没有cloudbees-folder插件 需要去 https://updates.jenkins-c ...

  3. auto_increment 自增长

    auto_increment create table t20( id int primary key auto_increment, (自增长必须为键) name char(16)); insert ...

  4. CentOS7 / CentOS8 设置终端屏幕分辨率

    Centos7 修改文件 /boot/grub2/grub.cfg 搜索 linux16 / /vmlinuz-3.10.0-123.el7.x86_64 root=UUID=881ac4e6-4a5 ...

  5. [bug] idea @Override is not allowed when implementing interface method

    解决 将idea环境jdk设置一致 参考 https://blog.csdn.net/shenya2/article/details/50460447 https://www.cnblogs.com/ ...

  6. [bug] java.sql.SQLException: Unknown initial character set index '255' received from server. Initial cl...

    参考 https://www.jianshu.com/p/d86de6463cbd

  7. [bug] Scala eclipse:找不到或无法加载主类

    原因 混合java 和scala 无法编译 解决 右键项目 > properties > scala Compiler >勾选Use Project Setting > Sca ...

  8. echo -n -e "请输入重启间隔的时间(分钟):\t"

    echo -n -e "请输入重启间隔的时间(分钟):\t"read interval##echo -n "Your choice is " # 加上 -n 可 ...

  9. VMware安装RedHat7、CentOS7后无网卡解决办法

    由于Vmware虚拟网卡和linux兼容问题导致驱动无法正常安装,默认的网卡类型不兼容找到我们的Vmware虚拟机文件夹,将VMware 虚拟机配置 (.vmx),追加一条设置,网卡类型etherne ...

  10. Wordpress用文件记录访客 IP和访问量

    1.记录访问量,显示访客IP [php原码] <?php /*打开文件用于记录访问量,如果文件不存在自动创建*/ $counterFile = "counter.txt"; ...