栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java的锁

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java的锁

一,synchronized关键字

synchronized是java的一个关键字,可以修饰方法和代码块,修饰方法会有一个ACC_SYNCHRONIZED标志,修饰代码快会有monitorEnter和monitorExit指令,这是在jvm之上的,修饰方法的也是会在方法开始前拿到monitor,所有synchronized都是通过MonitorObject来实现锁的,而MonitorObject会有一些队列,表示等待队列和和等待加锁队列,大家可以去看下源码,而每个synchronized都会对应一个锁对象,来记录锁的一些信息,jdk6后面的优化加入了锁消除,偏向锁,乐观锁和重量级锁,所消除就是如果jvm分析到没有锁竞争,或者是对象没有逃逸,那么就可以进行锁消除,如果锁的竞争很少,只有一个线程拿到锁,那么会记录偏向锁,如果锁的竞争不多,并且锁的持有时间不长,那么会升级到乐观锁,也就是自旋锁,如果竞争多,并且时间长,那么就是最后的重量级锁。

        这里不分析锁消除,偏向锁和自旋锁,因为他们都是jvm自己的优化,原理也比较简单,这里分析重量级锁。在操作系统中,操作系统提供一些原语,也就是原子操作,包括CAS,TS(Test and set) ,P ,V,这里CAS后面会说,TS是操作系统互斥锁的实现,而PV操作表示申请和释放资源,也可以用来实现互斥锁或者是共享锁,P表示如果资源<=0则循环等待,如果>0则进行-1操作,这个过程是原子的,也就是说,synchronized依赖于jvm的MonitorObject实现,MonitorObject依赖于操作系统底层的互斥锁原语实现

二,volatile关键字

        需要说明的是volatile并不能保证线程安全,只能保证线程可见性,也就是说线程A的修改,能够保证其他线程及时看到修改,并不能保证并发的安全性,那么他的原理是什么呢。

        volatile关键字编译成机器码后会看到这个关键字伴随的是一个#LOCK 指令,这个指令是处理器提供的一个信号,处理器收到LOCK后会对相应缓存进行锁定,一般是对整个缓存行进行锁定,如果缓存未对齐,或者是对应多个缓存行,则会进行总线锁定,而多个处理器核心之间通过缓存一致性协议来保证缓存的一致性,也就是缓存有四种状态

 如果一个核心修改了锁定的缓存行,则会立刻刷新到主存中,嗅探机制会将其他核心缓存行的数据设置为无效,那么核心将会从主存重新读取数据,这样保证的数据的可见性,而也正是因为有缓存锁的机制,volatile没有屏障,但是却有着屏障的功能,保证了有序性

详细的可以参考JVM LOCK#指令_dw147258dw的专栏-CSDN博客

也就是说volatile的成本就是缓存失效,修改数据后从主存读取数据

三,Lock接口

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/397210.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号