synchronized 和 ReentrantLock 区别
都是可重入锁
synchronized 是 JVM 层面的锁,是 java 关键字,Reentrantlock 是 lock 接口的实现,是 API 层面的锁
Reentrantlock 显式获得锁,释放锁,synchronized 隐式获取锁,释放锁
ReentrantLock 可响应中断,synchronized 是不可以响应中断的,阻塞的线程会一直阻塞
synchronized 的实现涉及到锁的升级,是同步阻塞,ReentrantLock 通过利用 CAS 自旋机制保证线程操作的原子性和 volatile 保证数据可见性,非同步阻塞,采用的是乐观并发策略
ReentrantLock 可以实现公平锁
ReentrantLock 可以通过 Condition 绑定多个条件
synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象,而 ReentrantLock 需要主动释放锁才能避免死锁
ReentrantLock 可以知道有没有成功获取锁,synchronized 不能
synchronized 锁的是对象,锁是保存到对象头里面的,根据对象头数据来标识是否有线程获得锁/争抢锁,ReentrantLock 锁的是线程,根据进入的线程和 int 类型的 state 标识锁的获得/争抢
synchronized 保证了那些特性
原子性: 确保线程互斥地访问同步代码
可见性: 保证共享变量的修改对其他线程可见。线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中获取最新的值。线程解锁前,必须把共享变量中的值刷新到主内存中。
有序性: 对一个监视器锁的释放操作先行发生于后面对该监视器锁的获取操作(happens-before)