1. 什么是重入锁?有哪些可重入锁?
- 重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层可以再次获取同一个锁,并且不发生死锁,这样的锁就叫做可重入锁。
- synchronized、ReentrantLock、ReentrantReadWriteLock
2. ReentrantLock(Lock)实现原理?(写的不好)
ReentrantLock(Lock)主要依靠volatile的state变量和CAS乐观锁来保证线程安全,使用AQS来管理等待的线程。
3. AQS是什么?底层实现? 同步队列,等待队列
- AbstractQueuedSynchronizer, 队列同步器,它是用来构建锁和其他同步组件的基础框架。
- AQS的实现依赖内部的同步队列(FIFO双向队列),如果当前线程获取同步状态失败,AQS会将该线程以及等待状态等信息构造成一个Node,将其加入同步队列的尾部,同时阻塞当前线程,当同步状态释放时,唤醒队列的头节点。
- 一个对象可以拥有同步队列和等待队列,调用wait()方法,会使当前线程进入等待队列并释 放锁,同时线程状态变为等待状态。如果一个线程获取了锁,并调用signal()方法,会将等待队列的首节点移动到同步队列并唤醒节点中的线程。
4. ReentrantLock公平和非公平原理?
ReentrantLock公平锁的TryAcquire里判断条件多了 hasQueuedPredecessors()方法,也就是判断当前节点是否有前驱节点,如果该方法返回true,则表示有线程比当前线程更早地请求获取锁,因此需要等待前驱线程获取并释放锁之后才能继续获取锁,而非公平锁的nonfairTryAcquire方法里没有hasQueuedPredecessors()方法,线程会直接去抢占锁,这就是公平锁和非公平锁的原理。
5. lock用法
方法 | 含义 |
---|---|
lock() | 获取不到锁会一直等待 |
lockInterruptibly() | 在等待获取锁的过程中可被中断 |
tryLock() | 获取到锁并返回true,获取不到并返回false |
tryLock(long time, TimeUnit unit) | 在指定时间内等待获取锁,过程中可被中断 |
6. 读写锁原理
- 读写锁在同一时刻可以允许多个读线程访问,读写锁维护了一对锁,一个读锁和一个写锁,读锁是一个共享锁,写锁是一个排他锁,在读操作时获取读锁。写操作时获取写锁。
- 当写锁被获取到时,后续其他线程的读写操作都会被阻塞,写锁释放之后,所有操作继续执行。当读锁被获取到时,后续的读操作不会被阻塞,其他线程的写操作会被阻塞,读写锁相比一般的排他锁性能有了很大提升。
- 另外,读写锁是可重入的,支持公平和非公平的锁获取方式,读写锁支持锁降低(一个线程先获取了写锁,又获取了读锁,接着释放了写锁,这就是锁降级)