不是一家人,不进一家门
二者同属于可重入锁,同一个线程可以重入上锁,不同的线程进行阻塞。
隐式:Synchronized,JVM系统层次,你看不到源码,是个关键字。
显式:ReentranLock,JDK层次,可以看到源码。
Synchronized
JDK1.6进行了哪些优化
1、为了减少获得锁和释放锁带来的性能消耗引入了偏向锁和轻量级锁。
2、获取锁的方式,改为锁升级过程。
锁的升级过程
1、同一线程优先,使用偏向锁。
2、再次获取锁,失败。
3、升级为轻量级锁,失败,进入自旋。
4、自旋一定次数后,升级为重量级锁。
五大特性
- 原子性
- 可见性
- 有序性
- 不可中断性
- 不可降级性
原子性:
一个线程执行过程中不可以收到其他线程因素的打断或者干扰,要么成功且正确的执行完毕,要么不执行。
可见性:
线程修改共享变量后,对其他线程可见,统一使用最新的数据。
有序性:
几行代码,禁止发生重排序行为,保证一行一行的有序执行。
不可中断性:
如果线程A拿到了锁,正在执行,线程A不释放锁,线程B和线程C永远不能拿到锁。
相比之下,lock中,线程的权利大很多。
如果线程A拿到了锁,正在执行,线程A一直磨磨唧唧的不释放锁,线程B不爽了,可以直接中断线程A,也可以直接退出不等了。
不可降级性:
你所使用的这个锁,升级为重量级锁后,就不能在降级了。
ReentrantLock
AQS
查看ReentrantLock源码得知,ReentrantLock这个锁已经生锈了,他已经不是他了,是一个寄生产品,里边全部都是Sync这个类的方法。
Sync继承了AQS类,AQS为队列同步器。
AQS中释放锁tryRelease与获取锁tryAcquire没有提供实现,由子类Sync提供了具体的实现。
AQS与CAS都是java.util .concurrent并发包下的东西。
CAS是基础,AQS是核心。
AQS中大量使用了volatile,为了保证多线程环境下数据的可见性及有序性。
ReentrantLock实现原理
参考:
https://blog.csdn.net/numbbe/article/details/113346849
如何实现公平锁
参考:
https://blog.csdn.net/numbbe/article/details/113243325
亮点
1、API很多,不像synchronized一样深不可测,ReentrantLock肉眼可见。
2、可以中断,等的不耐烦了,可以直接咔嚓,也可以自己走线程。
3、ReentrantLock的两点就是它各种各样的API,有各种各样的功能。