【Java并发编程】24、Synchronized实现原理解析
一、概述
我们知道在jdk1.5之前synchronized是一个重量级锁,相对于j.u.c.lock,它会显得那么笨重,以至于我们认为它不是那么的高效而慢慢摒弃它。
不过,随着后续java版本更新对synchronized进行的各种优化后,synchronized并不会显得那么重了。比如在jdk1.7中,concurrenthashmap中使用reentrantlock保证线程安全,而到了jdk1.8,又换成了使用synchronized来保证线程安全。说明synchronized的性能已经可以和reentrantlock相差不多了
二、实现原理
1、底层原理
2、详细说明
- 如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者;
- 如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1;
- 如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权;
3、两个队列
monitor中有两个队列,_waitset 和 _entrylist,用来保存objectwaiter对象列表( 每个等待锁的线程都会被封装成objectwaiter对象 ),_owner指向持有objectmonitor对象的线程,当多个线程同时访问一段同步代码时:
- 首先会进入 _entrylist 集合,当线程获取到对象的monitor后,进入 _owner区域并把monitor中的owner变量设置为当前线程,同时monitor中的计数器count加1;
- 若线程调用 wait() 方法,将释放当前持有的monitor,owner变量恢复为null,count自减1,同时该线程进入 waitset集合中等待被唤醒;
- 若当前线程执行完毕,也将释放monitor(锁)并复位count的值,以便其他线程进入获取monitor(锁);
4、公平性
5、内存结构
三、java虚拟机对synchronize的优化
1、锁的状态
锁主要存在四种状态,依次是:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁。但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级。
2、自旋锁和自适应自旋锁
线程的阻塞和唤醒需要cpu进行用户态和内核态的切换,切换过程会消耗cpu资源。如果占用锁的时间非常短,切换锁消耗的资源就得不尝试。
所以在这种情况下,引入了自旋锁和自适应自旋锁(循环一定的次数判断锁是否已经释放)
3、偏向锁
在大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让同一线程获得锁的代价更低,引进了偏向锁。
加锁处理流程
- 检测mark word是否为可偏向状态,即是否为偏向锁1,锁标识位为01;
- 若为可偏向状态,则测试线程id是否为当前线程id,如果是,则执行步骤(5),否则执行步骤(3);
- 如果测试线程id不为当前线程id,则通过cas操作竞争锁,竞争成功,则将mark word的线程id替换为当前线程id,否则执行线程(4);
- 通过cas竞争锁失败,证明当前存在多线程竞争情况,当到达全局安全点,获得偏向锁的线程被挂起,偏向锁升级为轻量级锁,然后被阻塞在安全点的线程继续往下执行同步代码块;
- 执行同步代码块;
- 暂停拥有偏向锁的线程;
- 判断锁对象是否还处于被锁定状态,否,则恢复到无锁状态(01),以允许其余线程竞争。是,则挂起持有锁的当前线程,并将指向当前线程的锁记录地址的指针放入对象头mark word,升级为轻量级锁状态(00),然后恢复持有锁的当前线程,进入轻量级锁的竞争模式;
4、轻量级锁
引入轻量级锁的主要目的是 在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗
“轻量级”是相对于使用操作系统互斥量来实现的传统锁而言的。但是,首先需要强调一点的是,轻量级锁并不是用来代替重量级锁的,它的本意是在没有多线程竞争的前提下,减少传统的重量级锁使用产生的性能消耗。
轻量级锁所适应的场景是线程交替执行同步块的情况,如果存在同一时间访问同一锁的情况,必然就会导致轻量级锁膨胀为重量级锁。
5、重量级锁
上一篇: 所有的内容创业者,都应0粉丝开始变现
下一篇: python实现感知器算法详解
推荐阅读
-
Java并发编程:Synchronized及其实现原理
-
并发编程(十三)—— Java 线程池 实现原理与源码深度解析 之 Executors(三)
-
Java网络编程之UDP实现原理解析
-
并发编程(十四)—— ScheduledThreadPoolExecutor 实现原理与源码深度解析 之 DelayedWorkQueue
-
Java并发(三):synchronized实现原理
-
Java并发之synchronized实现原理深入理解
-
Java并发编程深入理解之Synchronized的使用及底层原理详解 下
-
Java并发编程深入理解之Synchronized的使用及底层原理详解 上
-
java多线程Synchronized实现可见性原理解析
-
Java多线程高并发进阶篇(二)-synchronized实现原理剖析