当前位置: 首页 > news >正文

Java笔记-volatile和AtomicInteger

目录

  • 1. volatile
    • 1.1.什么是volatile
    • 1.2.JMM-Java内存模型
  • 2 验证volatile的特性
    • 2.1 可见性
    • 2.2.验证volatile不保证原子性
    • 2.3 volatile实现禁止指令重排序
  • 3.使用AtomicInteger解决volatile的不能实现原子性的问题
    • 3.2 AtomicInteger的方法说明:
    • 3.3 CAS
    • 3.4 应用

1. volatile

1.1.什么是volatile

volatile是Java虚拟机提供的轻量级的同步机制,保证了可见性和有序性(禁止指令重排序),保证了JMM三个特性中的两个

1.2.JMM-Java内存模型


JMM的三个特性:
可见性、有序性、原子性
可见性:

线程在自己的工作内存中修改了从主内存中拷贝的共享变量副本后,并把修改后的值重新传到主内存中进行更新。这时我们要保证其他线程第一时间也可以得到共享变量已经被修改的通知。这样就保证了线程之间的一个可见性(因为线程间是不能直接访问对方的工作内存,所以可以从主内存下手)
有序性:
禁止指令重排,避免多线程的环境下,程序出现乱序执行的现象。
指令重排:计算机在执行程序时,为了提高性能,编译器和处理器常常回对指令做重排


原子性:
某个线程正在做某个具体业务时,中间不可以被加塞或者被分割。需要整体完整,要么同时成功,要么同时失败。

2 验证volatile的特性

2.1 可见性

package volatileTest;class MyData{volatile int num=0;public void addTo60(){this.num=70;}
}
public class Test1 {public static void main(String[] args) {MyData data=new MyData();new Thread(()->{System.out.println(Thread.currentThread().getName() + "进来了。。。");try {Thread.sleep(3);//保证主线程已经得到了num=0} catch (InterruptedException e) {e.printStackTrace();}data.addTo60();System.out.println(Thread.currentThread().getName()+"将值改为"+data.num);},"AAA").start();while (data.num==0){}System.out.println(Thread.currentThread().getName() + "近啦了");System.out.println(Thread.currentThread().getName()+"获取num="+data.num);}
}


说明:num被voalite修饰,AAA线程执行了addTo60后,将num的值改为70,如果没有可见性的话,主线程main是不会感受到num已经被修改了,应该会一直循环,但结果表明,main并没有一直在循环体中,而是可以得到70这个值,所以表明,volatile修饰了变量,使其具有可见性

2.2.验证volatile不保证原子性

package volitileTest;
/*** 验证volatile不保证原子性*/
class Num{volatile int num=0;//20个线程对num进行加1操作,每个线程执行1000次,理论上应该为20000public void numAdd(){num++;}
}
public class Test2 {public static void main(String[] args) {Num obj=new Num();for(int i=1;i<=20;i++) {new Thread(()->{for(int j=0;j<1000;j++){obj.numAdd();}},String.valueOf(i)).start();}while (Thread.activeCount() > 2) {Thread.yield();}System.out.println(Thread.currentThread().getName()+"获取结果为:"+obj.num);}
}


说明:理论值应该是20000,但实际结果小于20000.
为什么不能保证原子性,因为没有锁,线程会进行争抢,不能及时将修改后的值写回主内存

2.3 volatile实现禁止指令重排序

3.使用AtomicInteger解决volatile的不能实现原子性的问题

package volitileTest;import java.util.concurrent.atomic.AtomicInteger;/*** 验证volatile不保证原子性* 解决不保证原子性的问题--AtomicInteger*/
class Num{volatile int num=0;//20个线程对num进行加1操作,理论上应该为20000public void numAdd(){num++;}AtomicInteger atomicInteger=new AtomicInteger();public void myAtomicAdd(){atomicInteger.getAndIncrement();//每次加1}
}
public class Test2 {public static void main(String[] args) {Num obj=new Num();for(int i=1;i<=20;i++) {new Thread(()->{for(int j=0;j<1000;j++){obj.numAdd();obj.myAtomicAdd();}},String.valueOf(i)).start();}while (Thread.activeCount() > 2) {Thread.yield();}System.out.println(Thread.currentThread().getName()+"获取结果为:"+obj.num);System.out.println(Thread.currentThread().getName()+"获取结果为:"+obj.atomicInteger);}
}


说明:可以看到使用了AtomicInteger后,得到的结果与预期相符

3.2 AtomicInteger的方法说明:

1.incermentAndGet()—相当于++i,先加1再返回


2.getAndIncrement()–相当于i++,先返回再加1

3.相同点,内部都调用了unsafe类的getAndAddInt()方法

可以看到为什么AtomicInteger能实现原子性,因为原理是CAS

3.3 CAS

CAS=Compare and Set
CAS是指,在这个操作中,如果AtomicInteger的当前值是prev,那么就更新为一个预期值(这里预期值是当前值加1),返回true。如果AtomicInteger的当前值不是prev,就什么也不干,返回false。通过CAS操作并配合do … while循环,即使其他线程修改了AtomicInteger的值,最终的结果也是正确的。

3.4 应用

使用java.util.concurrent.atomic提供的原子操作可以简化多线程编程:

1.原子操作实现了无锁的线程安全;

2.适用于计数器,累加器等。

相关文章:

Java笔记-volatile和AtomicInteger

目录1. volatile1.1.什么是volatile1.2.JMM-Java内存模型2 验证volatile的特性2.1 可见性2.2.验证volatile不保证原子性2.3 volatile实现禁止指令重排序3.使用AtomicInteger解决volatile的不能实现原子性的问题3.2 AtomicInteger的方法说明&#xff1a;3.3 CAS3.4 应用1. volat…...

[标准库]STM32F103R8T6 高级定时器--PWM输出和带死区互补PWM输出

前言 STM32F103系列的MCU&#xff0c;相比普通的51单片机&#xff0c;在输出硬件PWM这个功能上要强不少&#xff0c;两者实现的方式都类似&#xff0c;都是通过一个定时器来启用硬件PWM输出&#xff0c;不过在输出PWM通道的数量上&#xff0c;32F103要强上不少。仅通过一个高级…...

Camtasia2023最新版电脑视频录屏记录编辑软件

在Mac或Wind上有各种可用的视频记录和编辑软件&#xff0c;其中Camtasia被称为视频记录器和视频编辑器。录屏软件Camtasia2023到底有什么特色功能&#xff1f;本文将帮助您选择理想的选择来开始视频捕获&#xff0c;创建和编辑。Camtasia2023是Mac/win平台上一款使用非常简单的…...

管理用户安全性

每个数据库用户帐户都包括以下项&#xff1a;唯一的用户名验证方法 默认表空间临时表空间用户概要文件初始使用者组帐户状态验证用户口令验证、外部验证、全局验证管理员验证操作系统安全性&#xff1a;• DBA 必须具有创建或删除文件的操作系统权限。• 普通数据库用户不应具有…...

分享113个JS菜单导航,总有一款适合您

分享113个JS菜单导航&#xff0c;总有一款适合您 113个JS菜单导航下载链接&#xff1a;https://pan.baidu.com/s/1d4nnh-UAxNnSp9kfMBmPAw?pwdcw23 提取码&#xff1a;cw23 Python采集代码下载链接&#xff1a;https://wwgn.lanzoul.com/iKGwb0kye3wj base_url "http…...

RuoYi-Cloud 部署

RuoYi-Cloud部署 1. 下载 点击右侧链接可以进入gitee的源码下载地址&#xff1a; 偌依微服务源码gitee下载地址 2. 数据库部署 依据如下步骤创建系统所需数据环境&#xff0c;脚本执行没有先后次序要求&#xff1a; 在Mysql 中创建 ry-cloud 主数据库&#xff0c;并执行 …...

DockerFile文件详解

一、DockerFile文件说明1、概述 Dockerfile是用来构建Docker镜像的文本文件&#xff0c;文本内容包含了一条条构建镜像所需的指令、参数和说明。可以在Docker文件中使用RUN&#xff0c;CMD&#xff0c;FROM&#xff0c;EXPOSE&#xff0c;ENV等指令。即&#xff1a;Dockerfile仅…...

Java程序运行机制

Java语言既具有编译型语言的特征&#xff0c;又具有解释型语言的特征&#xff0c;Java程序要经过先编译后解释两个阶段。高级语言的运行机制&#x1f4cd;编译型语言使用专门的编译器&#xff0c;针对特定的平台&#xff08;移植性差&#xff09;&#xff0c;将高级语言的源代码…...

LeetCode刷题------字符串

目录 LeetCode&#xff1a;344.反转字符串 LeetCode&#xff1a;541. 反转字符串II LeetCode&#xff1a;剑指Offer 05.替换空格 LeetCode&#xff1a;151.翻转字符串里的单词 LeetCode&#xff1a;剑指Offer58-II.左旋转字符串 LeetCode&#xff1a;28. 实现 strStr() …...

区块链技术与应用2——BTC-数据结构

文章目录比特币中的数据结构1. 区块链&#xff08;block chain&#xff09;2. 默克尔树&#xff08;Merkle tree&#xff09;3.哈希指针的问题比特币中的数据结构 1. 区块链&#xff08;block chain&#xff09; 哈希指针&#xff1a; &#xff08;1&#xff09;保存数值的位置…...

BiseNet v1论文及其代码详解

来源&#xff1a;投稿 作者&#xff1a;蓬蓬奇 编辑&#xff1a;学姐 BiSeNet v1说明&#xff1a; 文章链接&#xff1a;https://arxiv.org/abs/1808.00897 官方开源代码&#xff1a;https://github.com/CoinCheung/BiSeNet &#xff08;本文未使用&#xff09; 文章标题&am…...

(超详细)Navicat的安装和激活,亲测有效

步骤一&#xff1a;准备安装包 下载Navicat&#xff0c;我用的v15最好一致&#xff08;私信可以发你安装包和注册码&#xff09;步骤二&#xff1a;关闭杀毒软件&#xff0c;然后需要断掉网络&#xff08;一定断网&#xff09; 步骤三&#xff1a;一路next安装&#xff0c;安装…...

JDY-31蓝牙模块使用指南

前言 本来是想买个hc-05&#xff0c;这种非常常用的模块&#xff0c;但是在优信电子买的时候&#xff0c;说有个可以替代的&#xff0c;没注意看&#xff0c;买回来折腾半天。 这个模块是从机模块&#xff0c;蓝牙模块分为主机从机和主从一体的&#xff0c;主机与从机的区别就…...

【2023】华为OD机试真题Java-题目0211-租车骑绿道

租车骑绿道 题目描述 部门组织绿道骑行团建活动。租用公共双人自行车骑行,每辆自行车最多坐两人、最大载重 M M M。 给出部门每个人的体重,请问最多需要租用多少双人自行车。 输入描述 第一行两个数字 m m m、...

leetcode: 3Sum

leetcode: 3Sum1. 题目描述2. 思考3. 解题3. 总结1. 题目描述 Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i ! j, i ! k, and j ! k, and nums[i] nums[j] nums[k] 0. Notice that the solution set must not contain …...

【Python学习笔记】26.Python3 输入和输出(2)

前言 本章节继续介绍Python的输入输出。 文件对象的方法 本节中剩下的例子假设已经创建了一个称为 f 的文件对象。 f.read() 为了读取一个文件的内容&#xff0c;调用 f.read(size), 这将读取一定数目的数据, 然后作为字符串或字节对象返回。 size 是一个可选的数字类型的…...

vue项目第二天

项目中使用element-ui库中文网https://element.eleme.cn/#/zh-CN安装命令npm install element-ui安装按需加载babel插件npm install babel-plugin-component -Dnpm i //可以通过npm i 的指令让配置刷新重新配置一下项目中使用element-ui组件抽离文件中按需使用element ui &…...

Python爬虫零基础到进阶(课程说明)

Python爬虫零基础到进阶 课程介绍总结 学—练—问 跟着学、多做多练、不懂就问、坚持就是胜利&#xff01; 作业 飞书布置&#xff0c;作业提交放到群里&#xff0c;老师批改。 代码量 python基础&#xff1a; 十一次课&#xff0c;学会python。环境安装&#xff08;了…...

《C++ Primer Plus》第16章:string类和标准模板库(13)

复习题 考虑下面的声明&#xff1a; class RQ1{ private:char *st; // pointer to C-style string public:RQ1() { st new char [1];strcpy(st, "");}RQ1(const char * s) {st new char [strlen(s)1];strcpy(st, s);}RQ1(const RQ1 & rq) {st new char[strlen…...

材质笔记 - Simluate Solid Surface

光的行为 当光和物体相遇时&#xff0c;光会有三种行为&#xff1a;被物体反射、穿过物体&#xff08;物体是透明或半透明的&#xff09;或者被吸收。 高光反射和漫反射 高光反射&#xff08;Specular Reflection&#xff09;会在表面光滑且反光的物体上看到&#xff0c;比如镜…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...