Synchronized 和 ReentrantLock的区别
1. 实现方法
Synchronized作为Jvm层面的锁,是java关键字,通过monitor完成,在指令运行时通过monitorenter和monitorexit来上锁,禁止指令重排。
ReentrantLock作为jdk所提供的API,由CAS保证数据的原子性和volatile保证数据可见性以实现锁。
2.
Synchrobnized不需要手动释放锁。
ReentrantLock需要手动上锁和解锁,如果没有解锁会造成死锁。
3.
Synchronized为 不可中断锁 和 非公平锁。
ReentrantLock为可中断锁和公平锁,ReentrantLock在抢不到锁而等待的时候可以中断操作,去做其它的事情。
4.
ReentrantLock可以结合Condition,实现复杂的多线程操作。
ReentrantLock通过绑定Condition结合await()/singal()方法实现线程的精确唤醒,
而synchronized不行。
Synchronized
本身会行成偏向锁/轻量级锁/重量级锁
偏向锁
记录第一个访问的线程,如果线程再访问,直接获得锁
轻量级锁
获取锁时另一个线程已经获取,通过自旋获取锁
重量级锁
锁竞争时间长时膨胀为重量级锁,其它竞争锁的线程直接Block阻塞。
Synchronized 的底层monitor的实现
Monitor 由C/C++编写,java调用。
Monitor中的主要属性为
Owner 记录锁的持有者
WaitSet 存放 wait 的线程
EntryList 存放锁 block状态的线程
Recursions 锁的重入次数
Count 线程获得锁的次数。
多个线程访问一段同步代码时,除获得锁的线程,其它线程进入等待队列,等owner变为null,阻塞队列的线程唤醒,去获得monitor。
参考&搬运 https://zhuanlan.zhihu.com/p/126085068