ReentrantLock 和 synchronized 都是悲观锁
ReentrantLock是可重入锁(获取多少次锁就要释放多少锁) 公平/非公平都可以
synchronized 可重入 非公平:
锁机制实现原理:
配合常量池中的ACC_SYNCHRONIZED标识位 通过竞争监视器或者说管程monitor(两个原语monitorenter monitorexit 同一个时刻,只有一个 进程/线程能进入monitor中定义的临界区——》 monitor 能够达到互斥的效果)来实现锁同步
非公平锁实现原理:
虽然synchronized是悲观锁 但是非公平实现原理在于在进入线程队列前进行CAS,所以新启动的线程可能可以优先获得:
顺便说下锁升级:
无锁 -----》偏向锁—》轻量级锁-----》再到重量级锁(涉及锁升级 所以在已经知道同步代码块竞争激烈的时候 可以直接用重量级锁 防止锁机制转换带来的开销~)
ReentrantReadWriteLock:
读写锁:允许同一时刻被多个读线程访问,但是当有写线程访问时就阻塞所有读写线程
可重入通过jvm 记下锁的持有线程和计数器进行实现
可通过逃逸分析变对象堆分配为栈分配 也降低锁竞争问题(因为栈中不同步就不需要锁)
总的来说 lock的优势:
1能够显示地获取和释放锁,锁的运用更灵活
(synchronized会在抛出异常时自动释放锁 但是阻塞的时候就会死锁 这时候其他请求该资源的线程可以用trylock 等不带不到就撤退!)
2可以方便地实现公平锁
3能够响应中断,非阻塞获取锁:lockInterruptibly(可响应中断)和tryLock(等待一定时间)方法及其实现可响应中断
4读操作时,线程之间不会发生冲突:利用读写锁读操作时,线程之间不会发生冲突ReentrantReadWriteLock
5通过Lock可以知道有没有成功获取锁(通过ReentrantLock) syncroniszed就不行
缺点:
1lock如果发生异常是不会像syncroniszed一样自动释放锁的 所以切记在finally中手动释放锁 要不很容易死锁
在竞争特别激烈的时候用lock会好 一般激烈的情况下lock和syncroniszed性能差不多~