1.简介
ReentrantLock可重入锁指线程可以重复获取同一把锁。但是,在它之前的Synchronized也可以实现可重入锁,那为什么还会创造出ReentrantLock呢?
2.原因
①性能方面。
当存在大量线程竞争锁时,多数情况下ReentrantLock的性能优于synchronized。因为在JDK6中对synchronized做了优化,在锁竞争不激烈的时候,多数情况下锁会停留在偏向锁和轻量级锁阶段,这两个阶段性能是很好的。当存在大量竞争时,可能会膨胀为重量级锁,性能下降,此时的ReentrantLock应该是优于synchronized的。
②公平性。
如果是公平的获取锁,就是说多个线程之间获取锁的时候要排队,依次获取锁;如果是不公平的获取锁,就是说多个线程获取锁的时候一哄而上,谁抢到是谁的。
由于synchronized是基于monitor机制实现的,它只支持非公平锁;但ReentrantLock同时支持公平锁和非公平锁。
3.ReentrantLock实现
①公平锁
初始化时,state=0,表示没有线程获得锁;等到线程A获得了锁,这时state+1,线程A没有释放锁之前,其它线程无法获得锁,而是生成节点进行排队,不会出现插队的情况。特别地,如果线程A又请求锁,是不需要排队的,而是state再+1,等到线程A把此锁全部释放了,即状态值减到0了,其他线程才有机会获取锁。
②非公平锁
当线程A执行完之后,要唤醒线程B是需要时间的,而且线程B醒来后还要再次竞争锁,所以如果在切换过程当中,来了一个线程C,那么线程C是有可能获取到锁的,如果C获取到了锁,B就只能继续乖乖休眠了。