线程操作原子性

Java多线程:线程操作的原子性问题 概述 : 原子性是指在一次操作或者多次操作中,要么所有的操作全部都得到了执行并且不会受到任何因素的干扰而中断,要么所有的操作都不执行,多个操作是一个不可以分割的整体。例如一个送冰淇淋的案例:开启100条线程,每个线程送100个冰淇淋。代码实现 : 运行结果如下: 从结果看出,最后不是10000个冰淇淋,有些count++操作被“打断”了。代码总结 : count++ 不是一个原子性操作, 他在执行的过程中,有可能被其他线程打断,并且说明 volatile关键字不能保证原子性解决方案 : 我们可以给coun 阅读详情

原子性

违反原子性示例

public  class Counter{
    volatile int i=0;
    public void add(){
        i++;
    }
    public static void main (String[]args)throws InterruptedExcetion{
        final Counter ct=new Counter();
        for(int i=0;i<6;i++){
            new Thread(new Runnable(){
                public void run(){
                    for(int j=0;j<10000;j++){
                        ct.add();
                    }
                }
            });
        }
        Thread.sleep(6000L);
        System.out.println(ct.i);
    }
}

上面代码是六个线程,每个线程执行一万遍i++;结果会小于6万,出现这种用的原因是:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CZYWNMID-1642648955464)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211215220044046.png)]

如上图所示,t1和t2进行i++操作,i++通过javap编译后看出经过getfileld(从主内存获取变量值)、iconst_1(入栈)、iadd、putfield(同步到主内存)等操作,t1和t2从主内存第一次获取i的初始值都是0,假如t1线程优先被执行,经过i++操作,i变成1写入到主内存,此时t2工作内存中的i还是之前的初始值0,经过i++后,t2将i=1同步到主内存,此时t2执行的i++相当于失效,所有i++6万次,可能有很多这样的失效操作,导致最后结果小于6万

解决方案

  1. 可以加入同步锁synchronized、Lock,这样的缺点因为是同步的,同时只支持一个并发
  2. 使用CAS实现的Automic工具类

CAS

概念

Compare and swap 比较和交换。属于硬件同步原语,处理器提供了基本内存操作的原子性保证。CAS操作需要输入两个数值,一个旧值A(期望操作前的值)和一个新值B,在操作期间先对旧值进行比较,若没有发生变化,才交换成新值,发生了变化则不交换。

CAS解决i++问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9gEqPtl9-1642648955467)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211215225551532.png)]

违反原子性示例的问题通过CAS操作进行解决:

线程进行相加操作,同步到主内存前没有进行CAS 对比操作,比如修改i的变量值同步到主内存前会将修改前的值和主内存中i的值进行对比,如果相等则将修改后的值1同步到主内存,这是t2将相加后的的值1(0,1)同步到主内存,这时经过对比t2线程的i旧值0和主内存中i的值1不相等,所以同步失败,此时t2会进入自悬状态,重新从主内存中加载 i 的值,然后i++操作,然后进行对比操作,到同步到主内存成功为止

CAS的三个问题

  1. 循环+CAS,自旋的实现让所有线程都处于高频运行(runable状态),争抢CPU执行时间的状态。如果操作长时间不成功,会带来很大的CPU资源浪费
  2. 仅针对单个变量的操作,不能用于多个变量来实现原子操作
  3. ABA问题

ABA问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7xNWUMcr-1642648955469)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211219122457972.png)]

如上图所示:

thread1、thread2同时读取到i=0后;thread1、thread2都要执行CAS(0,1)操作;假设thread2操作稍后于thread1,

则thread1执行成功;thread1紧接着执行了CAS(1,0),将i的值改回0,这样thread2执行CAS(0,1)预期是失败的,但是可以执行成功。

该问题可以通过版本号来解决,如使用AtomicStampedReference类

原子操作封装类

  1. AtomicBoolean :原子更新布尔类型
  2. AtomicInteger: 原子更新整型
  3. AtomicLong: 原子更新长整型
  4. AtomicIntegerArray: 原子更新整型数组里的元素
  5. AtomicLongArray: 原子更新长整型数组里的元素
  6. AtomicReferenceArray: 原子更新引用类型数组里的元素
  7. AtomicIntegerFieldUpdater: 原子更新整型的字段的更新器。
  8. AtomicStampedReference: 原子更新带有版本号的引用类型。
  9. AtomicStampedReference: 原子更新带有版本号的引用类型**(有效防止ABA问题)**

1.8更新

计数器增强版,高并发下性能更好

更新器: DoulbeAccumulator、LongAccumulator

计数器: DoubleAdder、LongAdder

原理: 分成多个操作单元,不同线程更新不同的单元,只需要汇总的时候才计算所有的单元操作。

场景: 高并发频繁更新、不太频繁地读取。

导致线程安全的原因

  1. 可见性
  2. 安全性
    分成多个操作单元,不同线程更新不同的单元,只需要汇总的时候才计算所有的单元操作。

场景: 高并发频繁更新、不太频繁地读取。

导致线程安全的原因

  1. 可见性
  2. 安全性
【硬件工程师职业细分】揭秘硬件基带工程师 你知道硬件工程师的细分领域硬件基带工程师吗? 它们和常见的硬件工程师又有哪些不同? 福利待遇怎么样?有哪些职业要求? 快来涨上一波知识吧~ 阅读详情

相关推荐

解决WSL2网络隔离:Ubuntu子系统共享Windows代理的3种方法

本文详细解析了WSL2的网络隔离特性,并提供了三种在Ubuntu子系统中共享Windows代理的实用方法:环境变量法、配置文件法和系统服务法。通过具体代码示例和方案对比,帮助开发者快速解决WSL2网络访问问题,实现一键设置代理,提升开发效率。

weixin_29295541的博客 452

JAVA线程基础二——原子性操作

使用 synchronized 关键字的确可以实现线程安全性,即内存可见性和原子性,但是synchronized 是独占锁,没有获取内部锁的线程会被阻塞掉,而这里的 getCount 方法只是读操作,多个线程同时调用不会存在线程安全问题。答案是肯定的,下面将讲到的在内部使用非阻塞CAS算法实现的原子性操作类AtomicLong 就是一个不错的选择。所谓原子性操作,是指执行一系列操作时,这些操作要么全部执行,要么全部不执行不存在只执行其中一部分的情况。那么如何才能保证多个操作的原子性呢?

weixin_45826852的博客 495

FPGA赋能:从加权灰度均值到快速收敛的自动曝光实战

本文深入探讨了FPGA在工业视觉自动曝光算法中的应用,重点介绍了加权灰度均值法的优化实现与快速收敛策略。通过硬件友好的算法改造和流水线架构设计,FPGA方案能在1帧内完成曝光调整,显著提升处理速度和能效比,适用于复杂光照条件下的工业检测场景。

weixin_29306317的博客 83

Java多线程之原子性操作

        何谓原子性操作,即为最小的操作单元,比如i=1,就是一个原子性操作,这个过程只涉及一个赋值操作。又如i++就不是一个原子操作,它相当于语句i=i+1;这里包括读取i,i+1,结果写入内存三个操作单元。因此如果操作不符合原子性操作,那么整个语句的执行就会出现混乱,导致出现错误的结果,从而导致线程安全问题。因此,在多线程中需要保证线程安全问题,就应该保证操作的原子性,那么如何保证操作的...

carson0408的博客 5042

FPGA新手必看:Create HDL Wrapper和Generating Output Products到底该先用哪个?

本文深入解析了FPGA设计中Create HDL Wrapper与Generating Output Products的正确使用顺序,帮助新手避免常见错误。详细介绍了两者的功能差异、执行顺序的底层逻辑以及工程管理的最佳实践,特别适合使用Vivado进行FPGA开发的初学者。

xk7n92h3p5m的博客 1065

【COMSOL】将一个面上数据导出CSV或txt格式的方法

在COMSOL中参数化扫描后,把一个面上或体里的数据按照CSV或TXT格式导出的方法。

dave496206的博客 2994

线程的原子操作(原子性)理解

原子操作(原子性) 所谓的原子操作是指不会被线程的调度机制所打断的操作;这种操作一旦开始就一直运行到结束,在执行一个线程的过程中不会切换到其他线程中去。 单线程与多线程的个自定义 在单线程中,能够在单条指令中完成的操作都可以认为是“原子操作”,因为中断和切换只能发生在指令之间。 tips:Redis单命令的原子性主要得益于Redis的单线程 在多线程中,不能被其他进程或线程打断的操作就叫原子操作 ...

P_ning的博客 1774

Cox构建预测模型(5):如何用R语言绘制校准曲线(附全套代码)

这篇文献通过绘制两个模型的DCA曲线来评估模型的临床决策实际需求,一个是列线图模型,包括纳入列线图的全部变量,一个是TNM模型,只纳入TNM分期3个变量。A图是训练集1年、3年、5年患者的总生存期的DCA曲线;B图是训练集1年、3年、5年患者的总生存期的DCA曲线,红色线条代表列线图模型(包括构建模型的10个变量),黄色线条代表TNM模型(仅纳入TNM分期3个变量),两个模型对比,在绘制校准图之前,必须要完成数据的导入、拆分数据集的工作、预测因子的筛选,校准图的绘制是分别在训练集与验证集独立进行的。

qq_37610365的博客 1360

单片机 原子性操作_多线程程序中操作的原子性

(给CPP开发者加星标,提升C/C++技能)来源:Guancheng (G.C.)0. 背景原子操作就是不可再分的操作。在多线程程序中原子操作是一个非常重要的概念,它常常用来实现一些同步机制,同时也是一些常见的多线程Bug的源头。本文主要讨论了三个问题:1. 多线程程序中对变量的读写操作是否是原子的?2. 多线程程序中对Bit field(位域)的读写操作是否是线程安全的?3. 程序员该...

weixin_29584723的博客 821

【YOLOv8科研级创新】集成HS-FPN特征融合网络,让Neck模块在参数量锐减100W的同时精度跃升

打开确保模型解析器能识别HS_FPN模块。通过将HS-FPN集成到YOLOv8中,我们实现了一个“轻量级多尺度特征融合+精准检测”的目标检测模型。这个改进不仅在工程上能提升多尺度、细粒度场景的检测效果并降低部署成本,更在科研上提供了“选择性轻量级特征融合”的创新思路——这种思路可以延伸到其他检测网络(如Faster R-CNN、SSD)的Neck模块改进中,帮你在论文中打造独特的研究点。

m0_64661770的博客 138

嵌入式开发环境Vscode开发STM32单片机程序

STM32单片机非常强大,大多数教程都是使用 keil 编译器,keil 是收费的而 gcc 是开源免费的。这里介绍一些使用 gcc +开发单片机程序的经验。(这里不解释 gcc 是什么)。

嵌入式技术开发 1845

多线程程序中操作的原子性

0. 背景原子操作就是不可再分的操作。在多线程程序中原子操作是一个非常重要的概念,它常常用来实现一些同步机制,同时也是一些常见的多线程Bug的源头。本文主要讨论了三个问题:1. 多线程程...

轻松学C语言 256

❤️爆肝十二万字《python从零到精通教程》,从零教你变大佬❤️(建议收藏)

文章目录强烈推荐系列教程,建议学起来!!一.pycharm下载安装二.python下载安装三.pycharm上配置python四.配置镜像源让你下载嗖嗖的快4.1pycharm内部配置4.2手动添加镜像源4.3永久配置镜像源五.插件安装(比如汉化?)5.1自动补码神器第一款5.2汉化pycharm5.3其它插件六.美女背景七.自定义脚本开头八、这个前言一定要看九、python入门十、python缩进十一、Python注释1.单行注释2.多行注释十二、Python 变量1.变量定义理解2. 变量名命名3. 分

全栈川川 26万+

黑马程序员_线程(3) 线程定时器&ThreadLoad&原子性操作

-------android培训、java培训、期待与您交流! ---------- 一.线程定时器 eg: package com.it; import java.util.*; public class TraditionalTimer { private static int count = 0; @SuppressWarnings("deprecation") p

java博客 1082

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

操作的原子性与线程安全

本案例来源于java zone社区,由于源代码里面存在一些自己开发的注解,我暂时没找到相关的文档,所以我做了一些修改。用的都是java SDK的API。 关于概念: 原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。 线程安全:就是多线程访问...

520

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【Java 并发编程】线程操作原子性问题 ( 问题业务场景分析 | 使用 synchronized 解决线程原子性问题 )

总结、 一、原子性问题示例、 二、线程操作原子性问题分析、 三、使用 synchronized 解决线程原子性问题、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1149

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Java_多线程_原子性操作

何谓原子性操作,即为最小的操作单元,比如i=1,就是一个原子性操作,这个过程只涉及一个赋值操作。又如i++就不是一个原子操作,它相当于语句i=i+1;这里包括读取i,i+1,结果写入内存三个操作单元。因此如果操作不符合原子性操作,那么整个语句的执行就会出现混乱,导致出现错误的结果,从而导致线程安全问题。因此,在多线程中需要保证线程安全问题,就应该保证操作的原子性,那么如何保证操作的原子性呢...

Bobit - 优快云博客 969
上一篇: 线程操作原子性
下一篇: 手写ReentarntLock
一切还来得及
博客等级 码龄11年 50粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值