java:CAS、ABA问题详解

news/2024/5/19 2:26:49 标签: java, jdk, 反射, 多线程

1、java中的原子性操作

所谓原子性操作,是指执行一系列操作时,这些操作要么全部执行,要么全部不执行,不存在只执行其中一部分的情况。

2、CAS方法

CAS即Compare and Swap,其是JDK提供的非阻塞原子性操作,它通过硬件保证了比较-更新操作的原子性。CAS有四个操作数,分别为:对象内存地址、对象中的变量的偏移量、变量预期值和新的值。其操作含义为:如果对象obj中内存偏移量为valueOffset的变量为expect,则使用新的值update替换旧的值expect。也就是说,更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。这是处理器提供的一个原子性指令。

3、ABA问题

比如说一个线程one从内存位置V中取出A,这时候另一个线程two也从内存中取出A,并且two进行了一些操作变成了B,然后two又将V位置的数据变成A,这时候线程one进行CAS操作发现内存中仍然是A,然后one操作成功

尽管线程one的CAS操作成功,但是不代表这个过程就是没有问题的。

4、Unsafe类

getUnsafe方法源码:

java">    @CallerSensitive
    public static Unsafe getUnsafe() {
        Class<?> caller = Reflection.getCallerClass();
        if (!VM.isSystemDomainLoader(caller.getClassLoader()))
            throw new SecurityException("Unsafe");
        return theUnsafe;
    }
  • VM.isSystemDomainLoader(caller.getClassLoader()):这里判断是不是Bootstrap加载器加载了TestUnSafe.class。如果没有这个限制,那么我们的应用程序就可以随意使用Unsafe做事情了,而Unsafe类可以直接操作内存,这是不安全的,所以JDK开发组特意做了这个限制,不让开发人员再正规渠道使用Unsafe类,而是在rt.jar包里面的核心类中使用Unsafe功能。

我们可以使用万能的反射来获取Unsafe实例方法:

java">public class UnSafeTest2 {
    static final Unsafe unsafe;

    static final long stateOffset;

    private volatile long state = 0;

    static {
        try {
            // 使用反射获取Unsafe的成员变量theUnsafe
            Field field = Unsafe.class.getDeclaredField("theUnsafe");

            // 设置为可存取
            field.setAccessible(true);

            // 获取该变量的值
            unsafe = (Unsafe) field.get(null);

            // 获取state在UnsafeTest2中的偏移量
            stateOffset = unsafe.objectFieldOffset(UnSafeTest2.class.getDeclaredField("state"));
        }catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
            throw new Error(e);
        }
    }

    public static void main(String[] args) {
        UnSafeTest2 test2 = new UnSafeTest2();
        Boolean flag = unsafe.compareAndSwapInt(test2, stateOffset, 0, 1);
        System.out.println(flag);
    }
}

 


http://www.niftyadmin.cn/n/748598.html

相关文章

apollo权限管理(五)

创建项目时&#xff0c;已经有项目管理的全部权限&#xff08;项目负责人&#xff09;&#xff0c;项目负责人可以分配项目的权限 一&#xff0c;项目分配权限 在项目首页的左下方点击项目管理 添加项目管理人 添加成功显示如下&#xff1a; 二&#xff0c;集群分配权限…

Java伪共享详解

1、什么是伪共享 在Cache内部是按行存储的&#xff0c;其中每一行称为一个Cache行。Cache行是Cache与主内存进行数据交换的单位&#xff0c;Cache行的大小一般为2的幂次数字节。 当CPU访问某个变量时&#xff0c;首先会去看CPU Cache内是否有该变量&#xff0c;如果有则直接从…

apollo高可用(三)

目标&#xff1a;搭建dev环境下的高可用 1.在之前搭建的apollo基础上&#xff0c;在搭建一个dev环境 2.修改数据库(注意两个dev公用一个apolloconfigdb) 修改apolloconfigdb下表serviceconfig&#xff0c;两个dev的eureka地址都添上&#xff08;就是apollo-configservice的地址…

如何使用easymock

https://blog.csdn.net/bradmatt/article/details/80811072 官网教程&#xff1a;https://www.easy-mock.com/docs

java中的锁详解

1、概述 锁像synchronized同步块一样&#xff0c;是一种线程同步机制&#xff0c;但比java中的synchronized同步块更复杂。在java5之前锁是由synchronized同步块实现的&#xff0c;所以不能完全摆脱synchronized关键字。 自Java5开始&#xff0c;java.util.concurrent.locks包…

ngrok使用教程

下载地址&#xff1a; https://ngrok.com/ 关闭防火墙&#xff1a; 选检查防火墙状态 关闭防火墙 使用&#xff1a; ngrok http 8080 有效期&#xff1a;8小时

Java中ThreadLocalRandom类原理剖析

1、概述 ThreadLocalRandom类是JDK7在JUC包下新增的随机数生成器&#xff0c;它弥补了Random类在多线程下的缺陷。 2、Random类及其局限性 // java.util.Random的使用方法 public class RandomTest {public static void main(String[] args) {// 创建一个默认种子的随机数生…

springmvc整合 swagger

在线Demo: http://petstore.swagger.io Swagger官网&#xff1a;http://swagger.io GitHub地址&#xff1a;https://github.com/swagger-api 官方注解文档&#xff1a;http://docs.swagger.io/swagger-core/apidocs/index.html Swagger-UI地址&#xff1a;https://github.com/s…