前言:锁设计分类
java 5(jdk 1.5)以来,并发锁包(java.util.concurrent.locks)对于锁主要设计了两种锁(的实现):
1)ReentrantLock
2)ReadLock和WriteLock(实际来自于ReentrantReadWriteLock内部变量,下文有补充说明)
类继承体系
均实现父接口Lock,类继承体系图参考如下
ReentrantReadWriteLock类简述
1)类声明
注意,ReadLock和WriteLock为ReentrantReadWriteLock类的静态内部类,如下声明
2)ReentrantReadWriteLock实现的接口:ReadWriteLock
关于ReadWriteLock接口,和并发锁其实无特别关系,只是纯粹的接口,可理解是为了扩展管理,声明如下:
而ReentrantReadWriteLock内部实现此接口的覆盖方法,无疑是ReadLock和WriteLock的句柄实现,如下:
ReentrantReadWriteLock和ReentrantLock区别
1)ReentrantLock
ReentrantLock同synchronize关键字一样,是互斥锁。可以理解是作为synchronize关键字的替代和优化,优点是使用上更加灵活,扩展性也更强,但缺点也很明显,相对来说,代码量可能要稍多点。上手示例,参考以下链接:
关键的是,ReentrantLock如前所述,它是一个完全互斥的锁,即某一时刻永远只允许一个线程访问共享资源,不管是读数据的线程还是写数据的线程。如果并发线程数一上来,可能导致的结果就是:效率低下。
2)ReentrantReadWriteLock
相对ReentrantLock类说,ReentrantReadWriteLock类的出现很好的解决了它的不足。前以述及,该类(实现了ReadWriteLock接口)维护了两个锁:读锁(共享锁)和写锁(排他锁)。
ReentrantReadWriteLock类允许多个线程同时读取共享资源,但是如果其中有一个线程是写数据,那么其他线程就不能去读写该资源。即会出现三种情况:读读共享,写写互斥,读写互斥。换言之,多个线程如果都是读锁,则会同时执行(代码访问时间几乎相等),但是如果是写锁,则不会同时执行。