Java面试篇基础部分- 锁详解
可重入锁
可重入锁也叫作递归锁,是指在同一个线程中,在外层函数获取到该锁之后,内存的递归函数还可以获取到该锁。在Java语言环境下,ReentrantLock和Synchroinzed都是可重入锁的代表。
公平锁与非公平锁
- 公平锁(Fair Lock)是指在分配锁之前检查是否有线程在排队等待获取到锁,优先将锁分配给排队时间最长的线程。
- 非公平锁(Nonfair Lock)是指在分配锁的时候不考虑线程排队等待的情况,直接尝试获取锁的操作,在获取不到锁的情况下再排到队尾进行等待。如果获取到锁,则执行自己的业务逻辑。
因为公平锁需要在多核的情况下维护一个锁线程的等待队列,基于该队列进行锁的分配,因此效率比非公平锁要低很多。Java中Synchroinzed就是非公平锁,ReentrantLock默认的lock方法采用的也是非公平锁。
读写锁:ReadWriteLock
在Java中通过Lock接口以及其子类对象提供了方便对对象进行加锁和释放锁。但是这种锁是不能区分读写的。所以叫做普通锁。为了提高I/O性能,Java提供了读写锁机制。
读写锁分为读锁和写锁两种,多个读锁之间是不互斥的,读锁与写锁互斥。在读的地方使用读锁,在写的地方使用写锁,在没有写锁的情况下,读锁是无阻塞的。
如果系统的要求是共享数据可以同时支持多线程并发读的操作,但不能支持多线程并发写,那么使用读锁机制可以很大程度上增加读取效率;如果系统对于共享数据在同一时只能由一个线程进行写操作,并且在写的过程中不能进行读取,那么这个时候就需要使用写锁。因为读写锁之间是互斥的,所以说如果有写锁的话,读锁是没有办法进入的。
一般的情况下,分别定义一个读锁,一个写锁,在读取共享数据的时候使用读锁,在使用完成之后释放读锁,在写共享数据的时候使用写锁,在使用完成后释放写锁,在Java中提供了
java.util.concurrent.locks.ReadWriteLock的实现类ReentrantReadWriteLock来完成对读写锁的定义和使用。
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock