Java重入锁和读写锁怎么使用

  介绍

这篇文章主要介绍“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 假;   }

读写锁

Java重入锁和读写锁怎么使用