并发编程-JUC-原子类

JUC 整体概览

在这里插入图片描述

原子类

  • 基本类型-使用原子的方式更新基本类型
    • AtomicInteger:整形原子类
    • AtomicLong:长整型原子类
    • AtomicBoolean :布尔型原子类
  • 引用类型
    • AtomicReference:引用类型原子类
    • AtomicStampedReference:原子更新引用类型里的字段原子类
    • AtomicMarkableReference :原子更新带有标记位的引用类型
  • 数组类型-使用原子的方式更新数组里的某个元素
    • AtomicIntegerArray:整形数组原子类
    • AtomicLongArray:长整形数组原子类
    • AtomicReferenceArray :引用类型数组原子类
  • 对象的属性修改类型
    • AtomicIntegerFieldUpdater:原子更新整形字段的更新器
    • AtomicLongFieldUpdater:原子更新长整形字段的更新器
    • AtomicReferenceFieldUpdater :原子更新引用类形字段的更新器
  • JDK1.8新增类
    • DoubleAdder:双浮点型原子类
    • LongAdder:长整型原子类
    • DoubleAccumulator:类似DoubleAdder,但要更加灵活(要传入一个函数式接口)
    • LongAccumulator:类似LongAdder,但要更加灵活(要传入一个函数式接口)

原子类实现原理CAS

CAS其实就是执行一个函数:CAS(V,E,N)直到成功为止。

CAS操作涉及到三个操作数:
V:要读写的内存地址
E:进行比较的值 (预期值)这个期望值是每次自旋的时候从V中读取出来,然后更新的时候再比较这个值和V中的值是否相等如果相等表示没有其它线程来修改,否则被修改过,继续自旋。直到成功为止。
N:拟写入的新值

// 以AtomicInteger为例
public final int getAndAddInt(Object var1, long var2, int var4) {int var5;do {var5 = this.getIntVolatile(var1, var2);} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));return var5;}

compareAndSwapInt是一个native方法:

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe,
jobject obj, jlong offset, jint e, jint x))
UnsafeWrapper("Unsafe_CompareAndSwapInt");
oop p = JNIHandles::resolve(obj);//将Java对象解析成JVM的oop(普通对象指针)
//根据对象p内存地址和内存地址偏移量计算拟修改对象属性的地址
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
//基于cas比较并替换,x表示拟更新的值, addr表示要操作的内存地址, e表示预期值 这是一个原子的方法
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END

CAS存在的缺陷

主要存在三个缺陷:循环时间太长、只能保证一个共享变量原子操作、ABA问题。

  • 循环时间太长:如果CAS一直不成功呢?如果自旋CAS长时间地不成功,则会给CPU带来非常大的开销。
    • 原子类AtomicInteger#getAndIncrement()的方法
  • 只能保证一个共享变量原子操作:看了CAS的实现就知道这只能针对一个共享变量,如果是多个共享变量就只能使用锁了。
  • ABA问题:CAS需要检查操作值有没有发生改变,如果没有发生改变则更新。但是存在这样一种情况:如果一个值原来是A,变成了B,然后又变成了A,那么在CAS检查的时候会发现没有改变,但是实质上它已经发生了改变,这就是所谓的ABA问题。

ABA问题演示

public static void main(String[] args) {AtomicInteger at = new AtomicInteger(100);AtomicStampedReference<Integer> st = new AtomicStampedReference(100, 1);new Thread(() -> {// 值增1int i = at.incrementAndGet();System.out.println("AtomicInteger after modify : " + i);// 撤回修改 模拟 A -> Bint j = at.decrementAndGet();System.out.println("AtomicInteger after modify redo : " + j);// 值增1 版本号 + 1 为 2st.compareAndSet(st.getReference(), st.getReference() + 1, st.getStamp(), st.getStamp() + 1);System.out.println("AtomicStampedReference after modify : " + i + " version is : " + st.getStamp());// 撤回修改 模拟 A -> B 只不过这个时候我们携带了一个版本号 版本号 + 1 为 3st.compareAndSet(st.getReference(), st.getReference() - 1, st.getStamp(), st.getStamp() + 1);System.out.println("AtomicStampedReference after modify  redo : " + j + " version is : " + st.getStamp());}).start();new Thread(() -> {// 更新为102可以成功 这个数据其实是被改过一次at.compareAndSet(at.get(), at.get() + 2);System.out.println("AtomicInteger after modify in other Thread: " + at.get());// 更新为102不可以成功 获取的还是100 因为我们预期的版本号是1 也就是第一次的100 所以修改不成功st.compareAndSet(st.getReference(), st.getReference() + 2, 1, st.getStamp() + 1);// 没有修改成功所以版本号还是 3System.out.println("AtomicStampedReference after modify : " + st.getReference() + " version is : " + st.getStamp());}).start();}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

协调尺度:特征缩放在机器学习中的重要作用

目录 一、介绍 二、背景知识 三、了解功能缩放 四、特征缩放方法 五、特征缩放的重要性 六、实际意义 七、代码 八、结论 一、介绍 特征缩放是机器学习和数据分析预处理阶段的关键步骤&#xff0c;在优化各种算法的性能和效率方面起着至关重要的作用。本文深入探讨了特征缩放的…

LeetCode JS专栏刷题笔记(一)

一、前言 LeetCode 在前不久出了一个 JavaScript 专栏&#xff0c;这个专栏一个目的是为了非前端工程师学习 JS&#xff0c;另一个是为了前端工程师提升 JS 能力。 因此在这个专栏中&#xff0c;基本不涉及什么具体算法问题&#xff0c;都是一些 JS 的入门语法与常见的 JS 面…

【c++ debug】记一次protobuf结构相关的coredump问题

文章目录 1. 问题现象2. 问题描述3. 问题分析4. 问题根因5. 问题修复6. 补充&#xff1a;类成员变量定义为引用类型 1. 问题现象 其中curr_lanes是一个目标上一帧的当前车道current_lanes_curr_lane是lane_id对应的LaneInfo信息现象&#xff1a;在lane_info->lane().success…

【Java面试】MongoDB

目录 1、mongodb是什么&#xff1f;2、mongodb特点什么是NoSQL数据库&#xff1f;NoSQL和RDBMS有什么区别&#xff1f;在哪些情况下使用和不使用NoSQL数据库&#xff1f;NoSQL数据库有哪些类型?启用备份故障恢复需要多久什么是master或primary什么是secondary或slave系列文章版…

多模态基础---BERT

1. BERT简介 BERT用于将一个输入的句子转换为word_embedding&#xff0c;本质上是多个Transformer的Encoder堆叠在一起。 其中单个Transformer Encoder结构如下&#xff1a; BERT-Base采用了12个Transformer Encoder。 BERT-large采用了24个Transformer Encoder。 2. BERT的…

VPX信号处理卡设计原理图:9-基于DSP TMS320C6678+FPGA XC7V690T的6U VPX信号处理卡 信号处理 无线电通信

一、概述 本板卡基于标准6U VPX 架构&#xff0c;为通用高性能信号处理平台&#xff0c;系我公司自主研发。板卡采用一片TI DSP TMS320C6678和一片Xilinx公司Virtex 7系列的FPGA XC7V690T-2FFG1761I作为主处理器&#xff0c;Xilinx 的Aritex XC7A200T作为辅助处理器。XC7A2…

JVS智能BI的ETL数据集实践:数据自动化分析的秘诀

数据集是JVS-智能BI中承载数据、使用数据、管理数据的基础&#xff0c;同样也是构建数据分析的基础。可以通俗地将其理解为数据库中的普通的表&#xff0c;它来源于智能的ETL数据加工工具&#xff0c;可以将数据集进行分析图表、统计报表、数字大屏、数据服务等制作。 数据集管…

ElasticSearch之Index Template 和Dynamic Template

写在前面 在ElasticSearch之Mapping 一文中我们一起看了es的dynamic mapping机制&#xff0c;通过该机制允许我们不需要显式的定义mapping信息&#xff0c;而是es根据插入的文档值来自动生成 &#xff0c;比如插入如下的文档&#xff1a; {"firstName": "Chan…

初识 Rust 语言

目录 前言一、Rust 的背景二、Rust的特性三、部署开发环境&#xff0c;编写一个简单demo1、在ubuntu 20.04部署环境2、编写demo测试 四、如何看待Linux内核引入Rust 前言 自Linux 6.1起&#xff0c;初始的Rust基础设施被添加到Linux内核中。此后为了使内核驱动程序能够用Rust编…

第13章 网络 Page744~746 asio核心类 ip::tcp::endPoint

2. ip::tcp::endpoint ip::tcp::socket用于连接TCP服务端的 async_connect()方法的第一个入参是const endpoint_type& peer_endpoint. 此处的类型 endpoint_type 是 ip::tcp::endpoint 在 在 ip::tcp::socket 类内部的一个别名。 libucurl 库采用字符串URL表达目标的地…

Android开机不显示bootloader界面

Turn it off in the following way LINUX\android\bootable\bootloader\edk2\QcomModulePkg\Library\BootLib\MenuKeysDetection.c 试了没有生效 --- a/QcomModulePkg/Library/BootLib/MenuKeysDetection.cb/QcomModulePkg/Library/BootLib/MenuKeysDetection.c-364,7 364,8…

显微测量|台阶仪二维超精密测量微观形貌

台阶仪通过扫描被测样品表面&#xff0c;获取高分辨率的表面形貌数据&#xff0c;能够揭示微观结构的特征和性能。 标题了解工作原理和性能特点 台阶仪利用扫描探针在样品表面上进行微观测量&#xff0c;通过探测探针和样品表面之间的相互作用力&#xff0c;获取表面形貌信息…

数据分析 — 动画图 pyecharts

目录 一、概念二、安装和导入三、绘图逻辑四、绘图1、柱状图2、折线图3、散点图4、饼图5、南丁格尔图6、Geo() 地理坐标第7、Map() 绘制区域8、词云图9、层叠图10、3D 图11、仪表板 一、概念 Pyecharts 是一个基于 Echarts 的 Python 可视化库&#xff0c;它通过 Python 生成 …

云计算基础-快照与克隆

快照及克隆 什么是快照 快照是数据存储的某一时刻的状态记录&#xff0c;也就是把虚拟机当前的状态保存下来(快照不是备份&#xff0c;快照保存的是状态&#xff0c;备份保存的是副本) 快照优点 速度快&#xff0c;占用空间小 快照工作原理 在了解快照原理前&#xff0c;…

WordPress主题YIA移动端文章页的面包屑不显示怎么办?

平时我们一般都会在文章页导航菜单下方显示面包屑&#xff0c;类似于“当前位置&#xff1a;boke112百科 WordPress 正文”。平时用浏览器调试站点的时候&#xff0c;在Edge浏览器的“切换设备仿真”中&#xff0c;不管是选择什么设备都会显示面包屑。具体如下图所示&#xf…

抓包分析 TCP 协议

TCP 协议是在传输层中&#xff0c;一种面向连接的、可靠的、基于字节流的传输层通信协议。 环境准备 对接口测试工具进行分类&#xff0c;可以如下几类&#xff1a; 网络嗅探工具&#xff1a;tcpdump&#xff0c;wireshark 代理工具&#xff1a;fiddler&#xff0c;charles&…

3分钟了解Android中稳定性测试

一、什么是Monkey Monkey在英文里的含义是猴子&#xff0c;在测试行业的学名叫“猴子测试”&#xff0c;指的是没有测试经验的人甚至是根本不懂计算机的人&#xff08;就像一只猴子&#xff09;&#xff0c;不需要知道程序的任何用户交互方面的知识&#xff0c;给他一个程序&a…

LeetCode刷题计划

LeetCode刷题计划 推荐 代码随想录&#xff1a;https://github.com/youngyangyang04/leetcode-master 卡码网 练习ACM模式 https://kamacoder.com/ 01 #include <iostream> using namespace std;int main() {int a ,b;while(cin>>a>>b){cout<<ab<…

基于51/STM32单片机的智能药盒 物联网定时吃药 药品分类

功能介绍 以51/STM32单片机作为主控系统&#xff1b; LCD1602液晶显示当前时间、温湿度、药品重量 3次吃药时间、药品类目和药品数量 HX711压力采集当前药品重量 红外感应当前药盒是否打开 DS1302时钟芯片显示当前年月日、时分秒、星期 DHT11采集当前环境温度和湿度 …

【presto权威指南】presto介绍

需求&#xff1a;如何从众多数据源中快速处理数据 现实生产架构多源异构&#xff0c;需要一个强有力的工具&#xff08;抽象&#xff09;统一数据查询/分析 这也是presto/trino从诞生之初便贴数据湖查询工具 tag的原因&#xff0c;presto生来为此 生产环境的困境 1.数据源众多…