Java并发编程的艺术(三)————synchronized,volatile与final

本章节主要介绍多线程编程中用的比较多的三个关键词,分别是

synchronized, volatile, final

在开始之前首先要明白JMM模型的内容,即每个线程都是有自己本地的内存,用来存储变量和数据备份的。模型如下图:
在这里插入图片描述
具体可参见前一章Java并发编程的艺术(二)——Java内存模型

接下来一起进入这些关键字的世界~

1. synchronized

英文含义就是“同步”,非常的直接明了,就是用来让一些操作能被同步安全进行

问题:如何实现?
技术化说法:JVM通过进入和退出Monitor对象来实现的,查看汇编可以看到同步代码块前插入了monitorenter指令,同步代码块以monitorexit指令结束。
通俗:给存放东西的仓库上个锁,这个锁名字叫Monitor

2. volatile

英文含义为“容易改变的”,就是形容一个变量容易发生变化,但是我要让所有的人都知道它的变化过程。如果所有人都知道它怎么变化,大家不就能愉快的进行交流了嘛,因为大家获取到的信息量是一样的。

技术化表达:不允许自己本地内存存储的数据和主内存中不一样,被声明volatile的变量必须使得该数据同步到所有的线程,不管什么时候访问修改这个变量,所有的线程将立即知道。

问题:如何实现?
技术化说法:通过在volatile写和读操作前后加内存屏障,从而限制编译器处理器的重排序操作。

编译器在生成字节码时会在指令序列中插入内存屏障来禁止特定类型的重排序
当写一个volatile变量的时候,JMM会将该线程对应的本地内存中的共享变量值刷新到主内存中去
当读一个volatile变量的时候,JMM会把该线程对应的本地内存置为无效,线程接下来将从主内存中读取共享变量

通俗:给这个院子(内存空间)前后门(读和写)都上个锁,要求人们只能从前门进后门出,院子里还有个摄像头直播(线程间实时通信),大家都能第一时间看到院子里到底发生了什么。

两个关键字区别:

1.使用的方式不同

volatile是声明变量的,例如:

volatile int x;

synchronized用来声明代码块和方法的,例如

synchronized int getNum(){
    return number;
}

2.锁定的范围不同

volatile是针对部分变量,同步线程本地内存和主内存中变量的值,每次修改都让大家知道。
synchronized锁住本地内存,还锁住主内存,每次只允许一个线程执行。

3.开销不一样

volatile只同步部分内容,而且一旦发生变化,其他线程第一时间知道。
synchronized会让整个内存都被锁定住,每次只有一个线程运行,效率低下。

3. final

含义为“最终的,最后的结果”,可以引申为“不再变化的”
技术化说法:它只允许编译器赋值一次,被它修饰的变量值将不改变,和它绑定的对象一旦创建就无法改变引用。

所谓对象引用类似于指向存储在Java堆内的对象的指针。
具体可以绘制出以下的图:
在这里插入图片描述
对于int, long等变量,如果加上final后数值是不会改变的(因为只是变量)
但是对于对象这种引用类型,final限定的是对象引用不能改变,但要注意的是对象内存储的数据可以改变(可以理解为只满足始终接触的是同一个对象,与对象内部的数据没有任何关系)

这三个关键字可以说构建了多线程开发的半壁江山,很多优秀的库都是基于对这些关键字的巧妙使用来实现的,懂得这三个关键字就相当于你有了基本的工具去构建复杂的多线程系统:)

更多精彩内容:

Java并发编程的艺术(一)——Java并发的基础知识

Java并发编程的艺术(二)——Java内存模型

JVM学习:

跟我一起学JVM(一)——Java虚拟机的内存结构

跟我一起学习JVM(二)——Java对象的幕后

跟我一起学习JVM(三)——垃圾收集,刻不容缓

跟我一起学习JVM(四)——JVM调优总结与实例

跟我一起学习JVM(五)——类文件结构(咖啡宝贝)

跟我一起学习JVM(六)——类的加载机制

跟我一起学习JVM(七)——类加载器

喜欢的话转发分享,关注噢~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值