这篇文章主要介绍“Java重入锁和读写锁怎么使用”,在日常操作中,相信很多人在Java重入锁和读写锁怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答“Java重入锁和读写锁怎么使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
重入锁
重入锁ReentrantLock,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁。除此之外,该锁还支持获取锁时的公平和非公平性选择
所谓不支持重进入,可以考虑如下场景:当一个线程调用锁()方法获取锁之后,如果再次调用锁()方法,则该线程将会被自己阻塞,原因是在调用tryAcquire (int获得)方法时会返回假,从而导致线程阻塞
同步关键字隐式的支持重进入,比如一个同步修饰的递归方法,在方法执行时,执行线程在获取锁之后仍能连续多次地获得该锁.ReentrantLock虽然不能像同步关键字一样支持隐式的重进入,但在调用锁()方法时,已经获得锁的线程,能够再次调用锁()方法获取锁而不被阻塞
1。实现重进入
重进入特性的实现需要解决以下两个问题:
线程再次获取锁
锁需要去识别获取锁的线程是否为当前占据锁的线程,如果是,则再次成功获取
锁的最终释放
线程重复n次获取锁,随后在第n次释放该锁后,其他线程能获取到锁。实现此功能,理应考虑使用计数
ReentrantLock通过组合自定义同步器来实现锁的获取与释放,以非公平锁实现为例,获取同步状态的代码如下所示,主要是增加了再次获取同步状态的处理逻辑
final boolean nonfairTryAcquire (int 获得),{ ,final Thread current =, Thread.currentThread (); ,int c =, getState (); ,if (c ==, 0), { if 才能;(compareAndSetState(0,,获得),{ ,,setExclusiveOwnerThread(电流); ,,return 真实; ,,} ,} ,//判断当前线程是否为获取锁的线程 ,else if (current ==, getExclusiveOwnerThread ()), {//,才能将同步值进行增加,并返回,真的 int 才能;nextc =, c +,获得; if 才能;(nextc & lt;, 0) ,,throw new 错误(“Maximum  lock count exceeded"); 设置状态才能(nextc); return 才能;真实; ,} ,return 假; }
考虑到成功获取锁的线程再次获取锁,只是增加同步状态值,这也就要求ReentrantLock在释放同步状态时减少同步状态值,该方法代码如下:
protected final boolean tryRelease (int 版本),{ ,//减少状态值 ,int c =, getState(),安康;释放; ,if (Thread.currentThread (), !=, getExclusiveOwnerThread ()) throw 才能;new  IllegalMonitorStateException (); ,boolean free =,假; ,//当同步状态为0,将占有线程设为null,并返回真,表示释放成功 ,if (c ==, 0), { free =,才能正确; setExclusiveOwnerThread才能(空); ,} ,设置状态(c); ,return 自由; }
2。公平与非公平获取锁的区别
如果一个锁是公平的,那么锁的获取顺序就应该符合请求的绝对时间顺序,也即FIFO。回顾上一节,非公平锁只要CAS设置同步状态成功,即表示当前线程获取了锁,而公平锁则不同,代码如下:
protected final boolean tryAcquire (int 获得),{ ,final Thread current =, Thread.currentThread (); ,int c =, getState (); ,if (c ==, 0), {/*,才能 ,,*,唯一不同的就是判断条件多了,hasQueuedPredecessors () ,,*,该方法用来判断当前节点是否有前驱节点 ,,*,如果该方法返回,真的,表示有线程比当前线程更早请求获取锁 ,,*,因此需要等待前驱线程释放锁之后才能继续获取锁 ,,*/if 才能;(! hasQueuedPredecessors (),,,, compareAndSetState(0,,获得),{ ,,setExclusiveOwnerThread(电流); ,,return 真实; ,,} ,} ,else if (current ==, getExclusiveOwnerThread ()), { int 才能;nextc =, c +,获得; if 才能;(nextc & lt;, 0) ,,throw new 错误(“Maximum  lock count exceeded"); 设置状态才能(nextc); return 才能;真实; ,} ,return 假; }