一、概述
重入锁ReentrantLock,就是支持重进入的锁 ,它表示该锁能够支持一个线程对资源的重复加锁。支持公平性与非公平性选择,默认为非公平。
以下梳理ReentrantLock。作为依赖于AbstractQueuedSynchronizer。 所以要理解ReentrantLock,先要理解AQS。013-AbstractQueuedSynchronizer-用于构建锁和同步容器的框架、独占锁与共享锁的获取与释放
aqs有多神奇,让ReentrantLock没有使用更“高级”的机器指令,也不依靠JDK编译时的特殊处理,就完成了代码的并发访问控制。
重进入是指任意线程在获取到锁之后能够再次获取该锁而不被锁所阻塞,需要解决两个问题:
1) 线程再次获取锁(锁需要识别获取锁的线程是否未当前占据锁的线程)
2)锁的最终释放(要求锁对于获取进行计数自增,锁释放技数自减。技数=0表示锁已经成功释放)
1.1、Lock定义以及说明
public interface Lock { // 获取锁,若当前lock被其他线程获取;则此线程阻塞等待lock被释放 // 如果采用Lock,必须主动去释放锁,并且在发生异常时,不会自动释放锁 void lock(); // 获取锁,若当前锁不可用(被其他线程获取); // 则阻塞线程,等待获取锁,则这个线程能够响应中断,即中断线程的等待状态 void lockInterruptibly() throws InterruptedException; // 来尝试获取锁,如果获取成功,则返回true; // 如果获取失败(即锁已被其他线程获取),则返回false // 也就是说,这个方法无论如何都会立即返回 boolean tryLock(); // 在拿不到锁时会等待一定的时间 // 等待过程中,可以被中断 // 超过时间,依然获取不到,则返回false;否则返回true boolean tryLock(long time, TimeUnit unit) throws InterruptedException; // 释放锁 void unlock(); // 返回一个绑定该lock的Condtion对象 // 在Condition#await()之前,锁会被该线程持有 // Condition#await() 会自动释放锁,在wait返回之后,会自动获取锁 Condition newCondition(); }