博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JVM系列(四)— 原子性、可见性与有序性
阅读量:4694 次
发布时间:2019-06-09

本文共 1285 字,大约阅读时间需要 4 分钟。

上一篇讲了Java内存模型的相关知识,模型设计正是围绕着并发过程中如何处理原子性,可见性和有序性这3个特征来建立的

一、原子性(Atomicity)

  原子性的概念无需多说,熟悉事物的4个特性的应该比较熟悉这个概念

  由Java内存模型来直接保证的原子性变量操作包括read,load,assign,use,store,write。我们大致可以认为基本数

据类型的访问读写是具备原子性的(double和long有非原子性协定,不过读者只要知道就可以了,无须在意这两种几乎不会

发生的例外)

  如果应用场景需要提供更大范围的原子性保证,Java内存模型还提供了lock和unlock操作来满足这种需求,虚拟机未把

这两种操作直接开放给用户使用,但是提供了更高层次的字节码指令:monitorenter和monitorexit来隐式的使用这两个操作,

这两个字节码反映到Java代码中就是同步块——synchronized关键字,因此,在synchronized块之间的操作具备原子性

二、可见性(Visibility)

  可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。

  上一篇详细讲了volatile变量的一些特性,与普通变量的区别是,volatile的特殊规则保证了新值能立即同步到主内存,以

及每次使用前立即从主内存刷新。因此volatile变量保证了多线程操作时变量的可见性。

  除了volatile,Java还有两个关键字也实现了可见性:synchronized和final。

  synchronized同步块的可见性,是由"对一个变量执行unlock操作之前,必须先把此变量同步回主内存中(执行store和

write)"这条规则获得的,而final关键字的可见性是指:被final修饰的字段在构造器中一旦初始化完成,其他字段就能看见

final字段的值,也就是final域能确保初始化过程的安全性。

三、有序性(Ordering)

  一句话:如果在本线程内观察,所有的操作都是有序的;如果在一个线程中观察另一个线程,所有的操作都是无序的。

前半句是指"线程内表现为串行的语义";后半句是指"指令重排序"现象和"工作内存与主内存同步延迟"现象。

  Java提供了两个关键字来保证有序性:volatile和synchronized,volatile本身包含禁止指令重排序的语义,synchronized

则是由"一个变量在同一个时刻只允许一条线程对其进行lock操作"的规则来获得。

结语:

  以上介绍了并发中3种重要的特性,有没有发现,synchronized关键字满足了全部3种特性,看起来是万能的,的确,大部分

并发控制操作都能用synchronized来实现,,但是这也造就了他对性能的影响,在下篇我会介绍下以虚拟机角度看,有关

锁优化的知识,也可能,关于并发的介绍全部挪到《Java并发编程实践》这一分类中

 

转载于:https://www.cnblogs.com/yb38156/p/9433579.html

你可能感兴趣的文章
Android Handle 机制
查看>>
用中文命名API的意义和途径
查看>>
nfs服务
查看>>
【方法】原生js实现方法ajax封装
查看>>
【解决】Vue项目打包后打开index.html页面显示空白以及图片路径错误的问题
查看>>
【知识】location.search获取中文时候会被编码成一串字符
查看>>
【webpack4】webpack4配置及需要注意的问题
查看>>
typescript用vue-property-decorator在vue中的遇到的坑
查看>>
Mysql存储引擎--MyISAM与InnoDB的底层数据结构
查看>>
Mysql索引底层数据结构
查看>>
sublime Emmet的用法及相关语法
查看>>
如何安装 Composer
查看>>
Laravel 的 Blade 模板引擎,当数据存在时输出变量
查看>>
指针的小细节
查看>>
c++多态的一个示范
查看>>
c++纯虚函数和抽象类
查看>>
c++内存分区模型(四个区)
查看>>
线性求逆元
查看>>
欧拉函数求法(N)
查看>>
HDU6581 Vacation (HDU2019多校第一场1004)
查看>>