版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、JVMsynchronized的?Java 中存在两种锁机制:synchronized Lock,Lock JDK5 增加的内容,其作者是大名鼎鼎的并发专家Doug Leasynchronized 孰优孰劣,只是介绍二者的实现原理。 给出的答案是在软件层面依JVMLock CPU 指令问:JVM synchronized 的?JVMHotspot的6u23synchronized的实现: synrhronized Lock 广泛。其应用层的语义是可以把任何一个非null对象作锁,当synchronized作用在方法上时,锁住的便是对象实例thi;当作用在静态方法时锁住的便是对象对应的Class
2、实例,因为Class 数据存在于永久带,因此静态方法锁相当于该类的一个全局锁;当synchronized 作用于某一个对象实例时锁住的便是对应的代码块在 HotSpot JVM 实现中锁有个专门的名字:对象监视器。线程状态及状态转换当多个线程同时请求某个对象监视器时,对象监视器会设置几种状态用来区分请求的线程:Contention List:所有请求锁的线程将被首先放置到该竞争队列EntryList:ContentionList中那些有资格成为候选人的线程被移到EntryWait wait Wait Set OnDeck:任何时刻最多只能有一个线程正在竞争锁,该线程称为OnDeck Owner
3、Owner!Owner:释放锁的线程下图反映了个状态转换关系:新请求锁的线程将首先被加入到 ConetentionList (Owner 状态unlock EntryList ContentionList EntryList,下ContentionList EntryList 的实现方式:ContentionList 虚拟队列ContentionList 并不是一个真正的QueuContentionListNode next 指 针逻辑构成,并不存在一个Queue ContentionList 是一个后进先出的队列,每次新加入Node CAS 改变第一个next Lock- Free 的队列。
4、Owner 线程才能从队尾取元素,也即线程出列操作无争用,当然也就避免了CAS 的 ABA 问题。EntryListEntryListContentionListContentionListEntryList。Ownerunlock时会从ContentionListEntryListEntryList中的某个线程(Head) 为 Ready(OnDeck)Owner 线程并不是把锁传递给 OnDeck 线程,只是把竞争锁的OnDeck,OnDeckHotspotOnDeck”。OnDeck owner EntryList 到公平性,在EntryList(依然在队头OwnerwaitWaitSe
5、t notify/notifyAll 自旋锁ContetionListEntryListWaitSet Linxu 下通 过 pthread_mutex_lock 函数。线程被阻塞后便进入内核调度状态,这个会导致系统在用户态与内核态之间来回切换,严重影响锁的性能Owner 线程能在很短的时间内释放锁,则那些正在争用线程可以稍微等一等(自旋, 在 Owner 线程释放锁后,Owner 运行的时间可能会超出了临(后退。基本思路就是自旋,不成功再阻塞,尽量降低阻塞的可能性,这对那些执行时间 很显然,自旋在多处理器上才有意义。还有个问题是,线程自旋时做些啥?其实啥都不做,可以执行几次for 循环,可以
6、执行几CPU 自旋优化策略对自旋锁周期的选择上,HotSpot 认为最佳时间应是一个线程上下文切换的时间,但目前并没有做到。经过调查,目前只是通过汇编暂停了几个 CPU 周期,除了自旋周期选择, HotSpot 还进行许多其他的自旋优化策略,具体如下:如果平均负载小于 CPUs 则一直自旋如果有超过(CPUs/2)个线程正在自旋,则后来线程直接阻塞如果正在自旋的线程发现 Owner 发生了变化则延迟自旋时间(自旋计数)或进入阻塞如果 CPU 处于节电模式则停止自旋CPU (CPU A CPU B 得知这个数据直接的时间差)自旋时会适当放弃线程优先级之间的差异synchronized Conte
7、ntionList 时,也即第Ready 线程的锁。自旋锁由每个监视对象维护,每个监视对象一个。JVM1.6偏向锁在 JVM1.6中引入了偏向锁,偏向锁主要解决无竞争下的锁性能问题,首先我们看下无竞争下锁存在什么问题:HotSpot/解锁都会涉及到一些CAS(比如对等待队列的CAS 操作CAS操作会延迟本地调用,因此偏向锁的想法是一旦线程第一次获得了监视对象,“”这个 线程,CAS true /。但还有很多概念需要解释、很多引入的问题需要解决:CASSMP架构CAS SMP(对称多处理器)SMP 的结构:其意思是所有的CPU BUBUS “”。CAS CPU CPU 比较CAS AtomicI
8、nteger类便是使用了这些封装后的接口。Core1Core2Load L1 Cache Core1 L1CacheCore2L1Cache失效”Core2L1Cache中的值失效(Cache命中缺失)则会通过总线从“Cache ,因为总 线被设计为固定的“”Cache 一致性流量过大,总线将成为瓶颈。而当Core1和Core2“Cache 一致 性”Cache 一致性流量。CAS Cache CAS 成功时必然会引起总线风暴,这就是所谓的本地延迟,本质上偏向锁就是为了消除CASCache 一致性流量。Cache 一致性:上面提到 Cache 一致性,其实是有协议支持的,现在通用的协议是MES
9、I(最早由 Intel开始支持 HYPERLINK /wiki/MESI_protocol /wiki/MESI_protoco,以后会仔细讲解这部分。Cache 一致性流量的例外情况:其实也不是所有的 CAS 都会导致总线风暴,这跟 Cache 一致性协议有关,具体参考: HYPERLINK /dave/entry/biased_locking_in_hotspot /dave/entry/biased_locking_in_hotspot NUMA(Non Uniform Memory Access Achitecture)架构:与 SMP 对应还有非对称多处理器架构,现在主要应用在一些高
10、端处理器上,主要特点是没有总线,没有公用主存,每个 Core 有自己的内存,针对这种结构此处不做讨论。偏向解除CAS代价的。总结关于锁,JVM 中还引入了一些其他技术比如锁膨胀等,这些与自旋锁、偏向锁相比影响不是很大,这里就不做介绍。通过上面的介绍可以看出,synchronized 的底层实现主要依靠 Lock-Free 思路是自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量。JVM 中的另一种锁 Lock 的实现前文(JVM-synchronized)JVMsynchronizedJVMLocksynchronized不同的是,LockJava 写成, javaJVM实现
11、的。java.util.concurrent.locks 包中有很多 Lock 的实现类,常用的有 ReentrantLockReadWriteLock ( 实 现 类 ReentrantReadWriteLock ) , 其 实 现 都 依 赖java.util.concurrent.AbstractQueuedSynchronizer 类,实现思路都大同小异,因此我们以ReentrantLock作为讲解切入点。ReentrantLock的调用过程经过观察 ReentrantLock 把所有 Lock 接口的操作都委派到一个 Sync 类上,该类继承了AbstractQueuedSynchr
12、onizer:view plainstaticabstractclassSyncextendsAbstractQueuedSynchronizer Sync又有两个子类:viewplainfinal static class NonfairSync extendsviewplainfinal static class FairSync extends Sync先理一下Reentrant.lock(方法的调用过程(默认非公平锁:Template AbstractQueuedSynchronizer ,AbstractQueuedSynchronizer LocktryAcquiretryAcqu
13、ire方法的语义在于AbstractQueuedSynchronizer 都将处理后面的流程。锁实现(加锁)简单说来,AbstractQueuedSynchronizer会把所有的请求线程构成一个CLH队列,当一个线程执行完毕(lock.unlock())时会激活自己的后继节点,但正在执行的线程并不在队列 中,而那些等待执行的线程全部处于阻塞状态,经过调查线程的显式阻塞是通过调用LockSupport.park()完成而LockSupport.park()则调用 sun.misc.Unsafe.park()本地方法再进一步在Linux中中通过调用pthread_mutex_lock函数把 线程
14、交给系统内核进行塞。该队列如图:synchronizedCLH CLH Doug Lea 把其改造为阻塞锁。synchronizedRunning线程,则新的竞争线程会被追加到队尾,具体是采用基于CAS Lock-FreeTailCASCAS失败,解决CAS AbstractQueuedSynchronizer不入细节 难以完全领会其精髓,下面详细说明实现过程:Sync.nonfairTryAcquirenonfairTryAcquire 方法将是 lock 用该方法。view plainfinalbooleannonfairTryAcquire(intacquires) finalThrea
15、dcurrent=Thread.currentThread(); intc=getState();if (c = 0) if (compareAndSetState(0, acquires) setExclusiveOwnerThread(current); return true;elseif(current=getExclusiveOwnerThread()intnextc=c+acquires;if (nextc 0) /*Predecessorwascancelled.Skipoverpredecessorsandindicateretry.*/do node.prev = pred
16、= pred.prev;while(pred.waitStatuspred.next =node;else /*waitStatusmustbe0orIndicatethatweneedasignal,butdontparkyet.Callerwillneedtoretrytomakesureitcannotacquirebeforeparking.*/compareAndSetWaitStatus(pred, ws,Node.SIGNAL);return false;检查原则在于:规则1SIGNALunparkacquireQueued12行(parkAndCheckInterrupt)将导
17、致线程阻塞规则2CANCELLED(ws0)到一个非取消的前继节点,返回 false,acquireQueued true,导致线程阻塞规则3:如果前继节点状态为非 SIGNAL、非 CANCELLED,则设置前继的状态为SIGNAL,返回 false 后进入 acquireQueued 的无限循环,与规则2同shouldParkAfterFailedAcquireCANCELLED 状态,则顺便删除这些节点重新构造队列。至此,锁住线程的逻辑已经完成,下面讨论解锁的过程。解锁请求锁不成功的线程会被挂起在 acquireQueued 方法的第12行,12行以后的代码必须等线程被解锁锁才能执行,假
18、如被阻塞的线程得到解锁,则执行第13行,即设置 interrupted = true,之后又进入无限循环。6行中调tryAccquire “”Headphead 的判断基本都会成功。tryAcquire展性,令人叹为观止!当然精妙的不是这个TemplaeDougLea对锁结构的精心布局。解锁代码相对简单,主要体现在 AbstractQueuedSynchronizer.release 和 Sync.tryRelease方法中:class AbstractQueuedSynchronizerview plainpublicfinalbooleanrelease(intarg)if (tryRel
19、ease(arg)Node h =head;if(h!=null&h.waitStatus!=unparkSuccessor(h);return true;return false;class Sync view plainprotectedfinalbooleantryRelease(intreleases)int c = getState() - releases;if (Thread.currentThread() != getExclusiveOwnerThread() thrownewIllegalMonitorStateException();booleanfree=if(c=0)
20、free = true; setExclusiveOwnerThread(null);setState(c); return free;tryRelease tryAcquire tryRelease status=0status 0CAS。release 的语义在于:如果可以释放锁,则唤醒队列第一个线程Head如下:view plainprivate void unparkSuccessor(Node node) /*Ifstatusisnegative(i.e.,possiblyneedingsignal)trytoclearinanticipationofsignalling.ItisOKifthisfails
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 沪教版三年级下册数学第二单元 用两位数乘除 测试卷带答案(夺分金卷)
- 沥青混凝土运输协议(35篇)
- 农村丧事礼仪主持词
- 讲文明懂礼貌演讲稿600字(35篇)
- 2024年三人联合承包石油化工工程合同2篇
- 设备购销合同格式示例
- 设计服务合同印花税的办理流程及指南
- 诚信在诉讼中的承诺
- 货物运输安全合作协议
- 购房合同补充协议解读
- 劳动实践教案:教室卫生整理
- 锦鲤养殖商业计划书
- 2024公基常识试题及答案解析(980题)
- 《酒精性心肌病》
- 红豆杉加工商业计划书
- 2023-2024学年成都市锦江区九年级上英语(一诊)期末考试题(含答案)
- DB37T 5235-2022 建筑施工附着式升降脚手架安全技术管理规程
- 一国两制课件
- 2024年蜀道集团招聘笔试参考题库含答案解析
- 年化妆品原料行业市场研究报告
- 量子随机数生成器
评论
0/150
提交评论