java八股文面试[多线程]——CAS同步机制

news2024/12/25 9:20:56

AtomicInteger 源码解析:

public class AtomicInteger extends Number implements java.io.Serializable {
    // 设置使用Unsafe.compareAndSwapInt进行更新
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;
 
    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                    (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) {
            throw new Error(ex);
        }
    }
    ...省略
    private volatile int value;
 
    //自动设置为给定值并返回旧值。
    public final int getAndSet(int newValue) {
        return unsafe.getAndSetInt(this, valueOffset, newValue);
    }
 
    //以原子方式将当前值加1并返回旧值。
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }
 
    //以原子方式将当前值减1并返回旧值。
    public final int getAndDecrement() {
        return unsafe.getAndAddInt(this, valueOffset, -1);
    }
 
    //原子地将给定值添加到当前值并返回旧值。
    public final int getAndAdd(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta);
    }
    ...省略
}

通过源码我们发现AtomicInteger的增减操作都调用了Unsafe 实例的方法,下面我们对Unsafe类做介绍:

Unsafe类
Unsafe 是位于 sun.misc 包下的一个类,Unsafe 提供了CAS 方法,直接通过native 方式(封装 C++代码)调用了底层的 CPU 指令 cmpxchg。
Unsafe类,翻译为中文:危险的,Unsafe全限定名是 sun.misc.Unsafe,从名字中我们可以看出来这个类对普通程序员来说是“危险”的,一般应用开发者不会用到这个类。
1、Unsafe 提供的 CAS 方法
主要如下: 定义在 Unsafe 类中的三个 “比较并交换”原子方法

/*
@param o 包含要修改的字段的对象
@param offset 字段在对象内的偏移量
@param expected 期望值(旧的值)
@param update 更新值(新的值)
@return true 更新成功 | false 更新失败
*/
public final native boolean compareAndSwapObject(Object o, long offset, Object expected, Object update);
public final native boolean compareAndSwapInt( Object o, long offset, int expected,int update);
public final native boolean compareAndSwapLong( Object o, long offset, long expected, long update);

Unsafe 提供的 CAS 方法包含四个入参: 包含要修改的字段对象、字段内存位置、预期原值及
新值。在执行 Unsafe 的 CAS 方法的时候,这些方法首先将内存位置的值与预期值(旧的值)比
较,如果相匹配,那么处理器会自动将该内存位置的值更新为新值,并返回 true ;如果不相匹配,处理器不做任何操作,并返回 false 。

2、获取属性偏移量
Unsafe 提供的获取字段(属性)偏移量的相关操作,主要如下:

/**
* @param o 需要操作属性的反射 
* @return 属性的偏移量 
*/ 
public native long staticFieldOffset(Field field); 
public native long objectFieldOffset(Field field);

staticFieldOffset 方法用于获取静态属性 Field 在 Class 对象中的偏移量,在 CAS 操作静态属性时,会用到这个偏移量
objectFieldOffset 方法用于获取非静态 Field (非静态属性)在 Object 实例中的偏移量,在 CAS 操作对象的非静态属性时,会用到这个偏移量。


3、根据属性的偏移量获取属性的最新值:

/**
* @param o 字段所属于的对象实例
* @param fieldOffset 字段的偏移量 
* @return 字段的最新值
*/
public native int getIntVolatile(Object o, long fieldOffset);

1.  ABA问题。因为CAS需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却变化了。

JDK 提供了两个类 AtomicStampedReferenceAtomicMarkableReference 来解决 ABA 问题。

2. 只能保证一个共享变量的原子操作。一个比较简单的规避方法为:把多个共享变量合并成一个共享变量来操作。 JDK 提供了 AtomicReference 类来保证引用对象之间的原子性,可以把多个变量放在一个 AtomicReference 实例后再进行 CAS 操作。比如有两个共享变量 i=1、j=2,可以将二者合并成一个对象,然后用 CAS 来操作该合并对象的 AtomicReference 引用。

3. 循环时间长开销大。高并发下N多线程同时去操作一个变量,会造成大量线程CAS失败,然后处于自旋状态,导致严重浪费CPU资源,降低了并发性。

解决 CAS 恶性空自旋的较为常见的方案为:
分散操作热点,使用 LongAdder 替代基础原子类 AtomicLong。
使用队列削峰,将发生 CAS 争用的线程加入一个队列中排队,降低 CAS 争用的激烈程度。JUC 中非常重要的基础类 AQS(抽象队列同步器)就是这么做的。
 

知识来源:

【23版面试突击】CAS是一种什么样的同步机制?_哔哩哔哩_bilibili

Java中CAS详解_java cas_LiWang__的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/948642.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

electron win系统通知修改通知标题栏

标题栏的 electron.app.Electron 如何修改: var package require("../package.json"); app.setAppUserModelId(package.description); app.setAppUserModelId 在主进程的app这里修改

git rebase和merge区别

一、概述 merge和rebase 标题上的两个命令:merge和rebase都是用来合并分支的。 这里不解释rebase命令,以及两个命令的原理,详细解释参考这里。 下面的内容主要说的是两者在实际操作中的区别。 1.1 什么是分支 分支就是便于多人在同一项目…

Python中object类的特殊方法

目录标题 前言一、object类的源码二、常用特殊方法解释1.__getattribute__方法2.__setattr__方法3.__delattr__方法4.__dir__方法5.__eq__和__hash__6.__ gt__、__ lt__、__ ge__、__ le__7.__str__和__repr__8.__new__方法9.__sizeof__方法10.__ class__、__ dict__、__ modul…

基于java swing和mysql实现的电影票购票管理系统(源码+数据库+运行指导视频)

一、项目简介 本项目是一套基于java swing和mysql实现的电影票购票管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、项目文档、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都…

Zabbix配置SNMP trap告警的例子

官方文档:3 SNMP 陷阱 1、安装Trap组件包 yum install -y net-snmp-utils net-snmp-perl net-snmp 2、下载并复制接收Trap脚本 wget https://sourceforge.net/projects/zabbix/files/ZABBIX%20Latest%20Stable/3.4.15/zabbix-3.4.15.tar.gzyum -y install tartar z…

计算机毕设 基于生成对抗网络的照片上色动态算法设计与实现 - 深度学习 opencv python

文章目录 1 前言1 课题背景2 GAN(生成对抗网络)2.1 简介2.2 基本原理 3 DeOldify 框架4 First Order Motion Model5 最后 1 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要…

买断制终身版的思维导图软件,大家有什么推荐?

思维导图是一种强大的工具,可以帮助我们组织思维、整理信息、提高效率。选择一款好用的思维导图软件对于个人和团队来说至关重要。本文将为大家推荐两款可以 闭眼入的终身版思维导图软件: boardmix 博思白板和MindMaster亿图脑图。 01 boardmix博思白板 …

生成动态柱状图【Python思路】

# 1.导包 import json from pyecharts.charts import Bar,Timeline from pyechasts.options import * from pyecharts.globals import ThemeType# 2.打开文件(此次数据格式.csv文件) f open("D:/data.csv","r",encoding"GB231…

项目开发尺寸像素问题

一般来说 项目开发开始会固定页面尺寸 一般都是1920x1080像素 那这样开发是最简单的我们直接用设计图的像素来开发就行 不用管有什么滚动条 一般浏览器都会有边框什么的 所以会出现滚动条 当我们全屏状态下其实才是我们想要页面结果 如果我们想没有滚动条开发 首先我们要知道…

上传图片不超过2M要怎么缩小?教你几招压缩图片

图片大小是我们在上传图片时经常遇到的问题,很多时候图片过大,导致无法正常上传到社交网络、邮箱或网站等其他地方,而解决这个问题的最直接方式就是将图片缩小。下面就给大家分享几个简单易行的方法,可以轻松将图片大小缩小到2M以…

C++设计模式_02_面向对象设计原则

文章目录 1. 面向对象设计,为什么?2. 重新认识面向对象3. 面向对象设计原则3.1 依赖倒置原则(DIP)3.2 开放封闭原则(OCP )3.3 单一职责原则( SRP )3.4 Liskov 替换原则 ( LSP )3.5 接口隔离原则 ( ISP )3.6 优先使用对象组合,而不是类继承3.7…

C++面向对象编程(2)

目录 一. 问题引入 二. 右值引用 1. lvalue/rvalue/prvalue/xvalue 1.1 表达式与对象的概念 1.2 左值与右值 2. moving semantics 2.1 显示绑定 2.2 Move constructors 2.3 Move assignment operator 2.4 实例分析 // TODO Quiz REF 本章简单介绍下move语义的“来…

数据通信——传输层TCP(可靠传输原理的停止等待协议)

引言 基于上次的基本特性中的可靠传输特性,我们对其进行详细的分析。 对了,在讲解TCP前,先对缓存进行一个简单的描述。我们都听说过缓存这个东西,我们发来的数据,会暂时写入到缓存中进行预处理,随后从缓存中…

OpenAI发布ChatGPT企业级版本

本周一(2023年8月28日)OpenAI 推出了 ChatGPT Enterprise,这是它在 4 月份推出的以业务为中心的订阅服务。该公司表示,根据新计划,不会使用任何业务数据或对话来训练其人工智能模型。 “我们的模型不会从你的使用情况中…

最适合家用的洗地机哪个牌子好?好用洗地机推荐

在如今的快节奏下,许多人没有太多的时间去完成家务清洁这一大问题,但是随着洗地机的出现,很多小伙伴们都发现了这个智能清洁家电在我们的生活中频繁出现,比如最近比较火爆的智能洗地机,结合了吸拖洗为一体的高效清洁与…

Bigemap 在水土生态环境行业中的应用

工具 Bigemap gis office地图软件 BIGEMAP GIS Office-全能版 Bigemap APP_卫星地图APP_高清卫星地图APP 使用场景: 1. 土地利用占地管理: 核对数据,查看企业的实际占地是否超出宗地,污染面积。不方便现场勘测的地方&#xf…

Python实操GetOpenFilename打开文件选择框获取工作表信息

import xlwings as xw xlapp xw.App(visibleTrue, add_bookFalse) a xlapp.api.GetOpenFilename(Excel Files (*.xl*),*.xl*, 0, 0, 0, True) print(a[0]) slist [] for i in a:wk xw.Book(i)for s in wk.sheets:s_dict {}s_dict[工作簿名字] wk.names_dict[工作表名字] …

K 次取反后最大化的数组和【贪心算法】

1005 . K 次取反后最大化的数组和 给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组: 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以这种方式修改数组后,返回数组 可能…

信看课堂笔记—LDO和DC-DC电路打PK

LDO(low dropout voltage regulator,低压差线性稳压器)和DC-DC(Direct current-Direct current converter,直流电压转直流电压转换器)电源是非常常见的电源电路,LDO 出来的比较早,像老戏骨一样,…

热烈祝贺天光长寿食品成功入选航天系统采购供应商库

经过航天系统采购平台的严审,单州天光长寿食品(单县)有限公司成功入选中国航天系统采购供应商库。航天系统采购平台是航天系统内企业采购专用平台,服务航天全球范围千亿采购需求,目前,已有华为、三一重工、…