JUC中的原子变量内部解析
前言
工作中用到的一些原子操作类,查看一下它们的源码,顺便复习学习和梳理一下之前遗忘的知识点。
在Java中的java.util.concurrent.atomic包下面的原子操作类截图:
主要知识点
1.原子变量
在Java代码中保证线程安全一般分成两种方式:锁和原子变量,这次的主题是原子变量。
原子变量能够保证原子性的操作,意思是某个任务在执行过程中,要么全部成功,要么全部失败回滚,恢复到执行之前的初态,不存在初态和成功之间的中间状态。例如CAS(Compare and Swap)操作,要么比较并交换成功,要么比较并交换失败。由CPU保证原子性。
通过原子变量可以实现线程安全。执行某个任务的时候,先假定不会有冲突,若不发生冲突,则直接执行成功;当发生冲突的时候,则执行失败,回滚再重新操作,直到不发生冲突。
2.CAS
CAS(Compare and Swap),一种无锁(lock-free)的非阻塞算法,翻译为:比较和交换。并且是CPU指令,在大多数处理器架构,包括IA32、Space中采用的都是CAS指令。
CAS是项乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
CAS无锁算法的C实现:
int compare_and_swap (int* reg, int oldval, int newval)
{
ATOMIC();
int old_reg_val = *reg;
if (old_reg_val == oldval)
*reg = newval;
END_ATOMIC();
return old_reg_val;
}
JVM对CAS的支持体现从JDK1.5中引入了底层的支持,在int、long和对象的引用等类型上都公开了CAS的操作,并且JVM把它们编译为底层硬件提供的最有效的方法。
3.魔法类:sun.misc.Unsafe
在原子变量中的方法底层实现的是利用Unsafe的CAS来实现原子操作的,其中Unsafe.compareAndSwap()用来实现高效的无锁数据结构。
这个类的提供了一些绕开JVM的更底层功能,直接申请和操作物理内存,基于它的实现可以提高效率。它所分配的内存需要手动free(不被GC回收)。
Unsafe的简单介绍:
(1)Unsafe类设计只提供给JVM信任的启动类加载器所使用,是一个典型的单例模式类;
(2)在Java中,可以用Unsafe绕过安全检查器。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Python各种命名规范
Python基础——(一)Python命名规范 (赠言)-希望大家浏览(或许有点搞笑):学习编程除了语言基础外什么比较重要呢?当然是命名和注释,对与一个优秀的程序员来说,一定有一个好的命名习惯(变量命名,函数命名,类命名.....)。别小看命名,否者以后会吃大亏,请相信我。大家在编程的过程中会不会不自主的运用,i,j,等简单字母命名(被我说中了吧,因为刚开始博主也是这样.....),这样对程序员来说简直是自杀,这时候肯定有的人会反驳博主了,有简单字母不用,还用英文单词么?这不傻X了吧。大家可能只考虑当时的方便却并没长远考虑。举个简单例子来说,假设你被天美工作室聘请,让你维护王者荣耀这款游戏,而其中这游戏的源程序全是这样的变量名(i,j,x,y,z),这时候你的心情是什么呢?你当时肯定在骂(这是哪个傻X写的变量,鬼知道这是什么,心中一万只草泥马奔腾)。如果变量是这样的呢:cat_number(表示猫的数量,而不是i,也不是j),这样是不是阅读程序就简单多了呢?遵循命名规范,对你,对我,对大家都会有好处-----------感谢大家花时间阅读个人的废话。 变量命名:变量需要遵循一定的命名规...
-
下一篇
python包引用问题
python模块引用梳理 文件组织结构: 复制代码t├── __init__.py├── main.py├── t1│ ├── A.py│ └── __init__.py└── t2 ├── B.py └── __init__.py 复制代码A.py def test(): print 't.t1.A.test()' B.py def test(): print 't.t2.B.test()' 执行: python t/main.py 问题1: 在main.py中引用t2/B的test方法,如何写? 方式1: from xxx import xxx from t2 import BB.test()这个写法很糟糕, 但能解决目前问题。糟糕的地方在于隐晦的引入t2。更好的方式是相对引用。 from .t2 import BB.test()但如果用 python t/main.py执行会报错,此处原因请参考这。原因是相对引用默认作为包的方式才能运行。 正确执行方法(linux shell下): python -m t.main 这个写法也不够好!B在具体的代码行,看不出其出处。更好的方式是 ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Redis,开启缓存,提高访问速度
- 2048小游戏-低调大师作品
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2全家桶,快速入门学习开发网站教程
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2更换Tomcat为Jetty,小型站点的福音