ReentrantLock详解
2018-08-26 17:20:04来源:博客园 阅读 ()
ReentrantLock概述
ReentrantLock是Lock接口的实现类,可以手动的对某一段进行加锁。ReentrantLock可重入锁,具有可重入性,并且支持可中断锁。其内部对锁的控制有两种实现,一种为公平锁,另一种为非公平锁。ReentrantLock的实现原理为volatile+CAS。
ReentrantLock可重入性
ReentrantLock具有可重入性,可重入性是指当一个线程拥有一个方法的锁以后,是否还可以进入该方法,一般这种情况出现在递归中。ReentrantLock的可重入性是基于Thread.currentThread()实现的,是线程粒度的,也就是说当前线程获得一个锁以后,当前线程的所有方法都可以获得这个锁。Reentrant依赖的锁只有两种实现类,NonFairSync和FairSync,但是它们获取锁的方式大同小异。一下是公平锁的获取实现。ReentrantLock.FairSync.tryAcquire
1 protected final boolean tryAcquire(int acquires) { 2 final Thread current = Thread.currentThread(); 3 int c = getState(); 4 //每一次加锁state+1 5 if (c == 0) { 6 if (!hasQueuedPredecessors() && 7 compareAndSetState(0, acquires)) { 8 setExclusiveOwnerThread(current); 9 return true; 10 //尝试获取锁成功 11 } 12 } 13 //是当前线程直接取到到锁,实现锁的可重入 14 else if (current == getExclusiveOwnerThread()) { 15 int nextc = c + acquires; 16 if (nextc < 0) 17 throw new Error("Maximum lock count exceeded"); 18 setState(nextc); 19 return true; 20 } 21 return false; 22 } 23 }
ReentrantLock锁的实现分析
ReentrantLock有两种锁的实现,FairSync和NonFairSync,对于这两种锁,他们获取锁的方式都大同小异ReentrantLock$Sync#acquire
1 public final void acquire(int arg) { 2 //通过tryAcquire去尝试获取锁,公平锁和非公平锁有不同的实现 3 if (!tryAcquire(arg) && 4 //如果没有获取到,就将该线程加入等待队列,然后循环尝试获取该锁 5 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) 6 //如果尝试获取锁的次数达到一定次数,就会触发中断,中断该线程,并释放锁 7 selfInterrupt(); 8 }
tryAcquire():尝试获取锁;
addWaiter():将线程加入等待队列
acquireQueued():在多次循环中尝试获取到锁或者将当前线程堵塞
selfInterrupt():如果多次未获取成功,将中断该线程(避免死锁)
公平锁(FairSync)
公平锁内部维护了一个等待获取该锁的线程的队列,会按照队列顺序给每个线程锁。每当抢占锁的时候,就会判断是否有等待队列,如果有等待队列,就从等待队列的头开始分配锁
1 protected final boolean tryAcquire(int acquires) { 2 //取得当前请求锁的线程 3 final Thread current = Thread.currentThread(); 4 //取得stage,每一次加锁,stage都会+1,如果stage是0,就说明,没有人使用该锁 5 int c = getState(); 6 if (c == 0) { 7 //如果没有等待队列,并且CAS通过,就将当前线程就抢到了锁 8 if (!hasQueuedPredecessors() && 9 compareAndSetState(0, acquires)) { 10 setExclusiveOwnerThread(current); 11 return true; 12 } 13 } 14 //如果锁没有释放,就判断当前线程是否是该锁的拥有者,如果是,可以直接使用该改,并stage+1 15 else if (current == getExclusiveOwnerThread()) { 16 int nextc = c + acquires; 17 if (nextc < 0) 18 throw new Error("Maximum lock count exceeded"); 19 setState(nextc); 20 return true; 21 } 22 //如果没有抢到锁,就返回false 23 return false; 24 }
非公平锁(NonFairSync)
非公平锁在抢占锁时,会进行随机抢占,后抢占的线程往往抢占到的几率比较大。
1 if (c == 0) { 2 //非公平锁仅仅是使用CAS,并不会去查看队列(也没有队列) 3 if (compareAndSetState(0, acquires)) { 4 setExclusiveOwnerThread(current); 5 return true; 6 } 7 }
ReentrantLock的内存可见性
ReentrantLock保证内存可见性,作用和synchronized一样,但是要比synchronized更加灵活,方便,ReentrantLock可以和Condition联合使用
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 数据源管理 | Kafka集群环境搭建,消息存储机制详解 2020-06-11
- Java--Stream流详解 2020-06-10
- B树和B+树的插入、删除图文详解 2020-06-09
- Spring Boot 2.3 新特性优雅停机详解 2020-06-08
- 详解SpringBoot(2.3)应用制作Docker镜像(官方方案) 2020-06-08
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash