可重入锁(ReentrantLock)浅析

ReentrantLock模型分类

可重入锁(ReentrantLock)有两种获取锁的模型,一种是公平锁,另一种是非公平锁,区别在于当前线程拥有锁之后,再次请求获取锁时,是否需要再次竞争锁资源

公平锁

初始化时,公平锁内部计数器(volatile int state)计0,无进程占有锁资源。

当线程A请求锁资源时,将 state + 1,此时state = 1,线程A占有锁资源。

此时有线程B请求锁资源,因锁内部计数器不为0,无可用资源,线程B进入等待队列等待锁资源的释放。

此时线程A再次请求锁资源,再次将 state + 1,state = 2 ,线程A仍然占有锁资源,线程B(其他线程)仍在等待队列等待锁资源的释放。

线程A每次释放锁资源,只会将计数器的值减一,即 state - 1 ,只有当state = 0 时,锁资源才全部释放,此时锁会通知队列唤醒线程B节点,线程B才能进行锁资源竞争,此时若有线程C在队列中,C线程继续休眠,只有当线程B执行结束,C才会被唤醒

当线程B获取锁资源后,线程A若再次请求锁资源,则需要通过锁资源竞争,且锁资源不被占用。


非公平锁

非公平锁和公平锁最大的区别在于,当线程A执行完后,锁资源释放,等待队列中有线程B,在唤醒线程B的过程中,若出现线程C请求锁,则线程C有很大机会获取该锁,一旦线程C拥有锁,则线程B继续休眠


ReenTrantLock独有的能力

1.      ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。ReentrantLock默认的构造函数是创建的非公平锁,可以通过参数true设为公平锁。

2.      ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,即可以绑定多个线程,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。

3.      ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。

你可能感兴趣的:(可重入锁(ReentrantLock)浅析)