浅谈一下Java中的ReentrantLock
一、ReentrantLock是用来做什么的?
这个类是JUC工具包中对线程安全问题提供的一种解决方案,它主要是用来给对象上锁,保证同一时间这能有一个线程在访问当前对象。这样处理是为了防止如果一个线程对某个公共变量进行了改变,而其它线程读取时读出来的是原有数据导致脏读的问题。
二、ReentrantLock的实现原理是什么?
ReentrantLock主要是通过同步队列和CAS机制来实现的,它实现的过程中主要包含下面几个属性:
- status:锁状态,0表示没有线程获取锁,1表示已有线程获取锁
- exclusiveOwnerThread:当前持有锁的线程
- Node:节点,是ReentrantLock内部维持的一个双向链表(同步阻塞队列)的基本构成
具体流程
1、上锁更新锁状态:当A线程持有锁时,会通过CAS将status状态置为1,并将A线程自身存入exclusiveOwnerThread属性当中;
2、线程入队:而后线程B通过CAS获取锁时发现无法获取锁,此时就会获取node信息,但是由于node双向链表是null所以会通过CAS来创建一个双向链表的head对象,之后再把线程B封装成的Node节点通过尾插法接入双向链表的尾部;
3、线程阻塞:入队完成后再调用park方法进行阻塞;
4、释放锁并更新锁状态:当A线程释放锁时会将status属性重置为0,且把exclusiveOwnerThread置为null;
5、唤醒线程:A线程释放锁完毕后会调用unpark方法来唤醒双向链表中下一节点的线程B;
三、ReentrantLock对比于Synchronized有哪些优缺点?
1、ReentrantLock的锁状态是可见的,而Synchronized的锁状态是不可见的;
2、ReentrantLock是JDK层面的实现,而Synchronized是JVM层面的实现;
3、ReentrantLock需要手动释放锁,而Synchronized不需要手动释放锁;
4、ReentrantLock可以是非公平锁也可以是公平锁,而Synchronized只能是非公平锁;
5、ReentrantLock是可被中断的,而Synchronized是不可悲中断的;
6、Synchronized在特定条件下是后来的线程先获取锁,而ReentrantLock是先来的线程先获取锁;
四、ReentrantLock的简单使用
static ReentrantLock lock = new ReentrantLock(); for (int i = 0; i < 10; i++) { Thread thread = new Thread(() -> { lock.lock(); try { for (int j = 0; j < 10000; j++) { sum++; } } finally { lock.unlock(); latch.countDown(); } }); thread.start(); }
到此这篇关于浅谈一下Java中的ReentrantLock的文章就介绍到这了,更多相关浅谈ReentrantLock内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Java基于Calendar类输出指定年份和月份的日历代码实例
这篇文章主要介绍了Java 使用Calendar类输出指定年份和月份的日历,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下2020-02-02Java类型转换valueOf与parseInt区别探讨解析
这篇文章主要为大家介绍了Java类型转换valueOf与parseInt区别探讨解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-09-09spring boot 配置freemarker及如何使用freemarker渲染页面
springboot中自带的页面渲染工具为thymeleaf 还有freemarker这两种模板引擎,本文重点给大家介绍spring boot 配置freemarker及如何使用freemarker渲染页面,感兴趣的朋友一起看看吧2023-10-10
最新评论