Java并发机制的底层实现

Java高级架构 2017-11-13 20:44:32

在Java并发实现的机制中,大部分的容器和框架都是依赖于volatile/synchronized/原子操作实现的,了解底层的并发机制,对于并发编程会带来很多帮助

一、 synchronized的应用

synchronized在多线程并发编程中已经是一个元老级的存在,通常被称作是重量级锁。既然是常用的一种锁,那么就需要对它的底层实现有深入的了解。

1. synchronized的实现原理

当一个线程在访问同步代码块时,就必须要先获取该代码块中对象的锁,退出或者抛出异常时,就必须要释放锁。synchronized的同步实现,是JVM基于进入和退出同步对象的Monitor对象来实现方法同步和代码块同步的。

每个Monitor对象都有与之关联的monitor,当且仅当monitor被持有后,它才会处于锁定状态。同步代码是使用monitorenter和monitorexit指令实现的。monitorenter指令时在代码编译后插入到同步代码块的开始位置,monitorexit指令则是插入到方法的结束和异常处。当线程执行到monitorenter时,会尝试去获取对象的monitor的所有权,即尝试获取对象的锁。

2. synchronized的使用形式及意义

  • 修饰普通方法:锁是当前实例对象

  • 修饰静态方法:锁是当前类的Class对象

  • 修饰代码块:锁是synchronized括号里面配置的对象

3. 锁的升级

锁共有四种状态:无锁状态->偏向锁状态->轻量级锁状态->重量级锁状态

偏向锁:当线程访问同步块并获取锁时,会在对象头和栈针中的锁记录中存储锁偏向的ID,以后该线程在进入和退出同步块时就不需要在使用CAS操作来进行加锁和解锁操作,而仅仅需要测试一下对象头中的Mark Word字段中存储的线程ID是否是当前线程即可。如果是,那么表示获取锁成功;如果不是,则需要检查对象头中偏向锁的字段是否设置为了1(表示当前锁是偏向锁),如果没有设置,则需要使用CAS来竞争获取锁,如果已经设置了,则尝试使用CAS将对象头的偏向锁ID指向当前线程。

轻量级锁;

  • 轻量级锁加锁:线程在执行同步块之前,首先会在自己的线程栈中创建一个用于存储锁记录的空间,并将对象中的Mark Word 赋值到锁记录中。然后线程尝试使用CAS操作将对象头中的Mark Word替换为指向锁记录的指针。如果成功,则表示当前线程获取锁,如果失败,则表示其他线程也在竞争锁,当前线程便使用自循的方式来获取锁。

  • 轻量级锁解锁:轻量级锁解锁时,会使用原子CAS操作将锁记录替换会对象头,如果成功,则表示没有竞争发生。如果失败,则表示当前锁存在竞争,锁就会膨胀为重量级锁。

4. 锁的对比

锁类型优点缺点适用场景
重量级锁线程竞争不使用自旋,不会浪费CPU线程阻塞,响应时间慢追求吞吐量,同步块执行的时间长的场景
轻量级锁竞争的线程不会阻塞,提高程序的响应速度如果线程长时间得不到锁,那么自旋就会浪费CPU追求响应时间,同步块执行速度快
偏向锁加锁和解锁不需要额外的资源消耗如果线程间存在竞争,会带来额外的锁撤销的消耗适用于只有一个线程访问同步场景

二、volatile的应用

volatile是轻量级的synchronized,volatile在多线程开发中保证了共享变量的可见性,所谓可见性,指的是当一个线程修改了共享变量之后,对于其他线程来说,能够读到这个修改的值。

1. volatile的定义及实现原理

volatile定义:Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁获得这个变量。

实现原理:当对声明了volatile的变量进行写操作时,JVM就会向处理器发送一条带有lock前缀的指令,将这个变量所在的缓存行的数据写回到系统内存中。同时,在多处理器的情况下,需要执行缓存一致性协议,即每个处理器都需要通过嗅探总线上传播的数据来检查自己的缓存是否过期,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置为无效,当处理器需要对这个数据进行操作时,再从系统内存中把数据读取到缓存行中。

2. 实现volatile的两条原则

  • 带有Lock前缀的指令会引起处理器缓存写回到内存;

  • 一个处理器的缓存写回到内存,会导致其他处理器的缓存无效。

1、具有1-5工作经验的,面对目前流行的技术不知从何下手,

需要突破技术瓶颈的。2、在公司待久了,过得很安逸,

但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的。

3、如果没有工作经验,但基础非常扎实,对java工作机制,

常用设计思想,常用java开发框架掌握熟练的。

4、觉得自己很牛B,一般需求都能搞定。

但是所学的知识点没有系统化,很难在技术领域继续突破的。

5. 群号:高级架构群 606187239备注好信息!

6.阿里Java高级大牛直播讲解知识点,分享知识,

多年工作经验的梳理和总结,带着大家全面、

科学地建立自己的技术体系和技术认知!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值