Java中的锁ReentrantLock详解
一、 ReentrantLock使用
1.1 简单使用
public class LockTest { // 新建锁 Lock lock = new ReentrantLock(); public static void main(String[] args) { // 测试 LockTest test = new LockTest(); test.te(); } public void te(){ try { // 获取锁 lock.lock(); System.out.println("获取到锁执行代码!"); } catch (Exception e) { e.printStackTrace(); } finally { // 一定注意 在finally中释放锁 lock.unlock(); } } }
1.2 tryLock
Lock比synchronized还是多一些功能的,比如可以设置规定时间内获取不到锁就返回,不一直阻塞。
一个不合时宜的例子就是:
synchronize就是一个舔狗,一直舔 直到天荒地老
lock 的 tryLock 就像是一个渣男,轻轻尝试一下,不合适抓紧下一个
public class LockTest02 { // 新建锁 Lock lock = new ReentrantLock(); public static void main(String[] args) { // 测试 LockTest02 test = new LockTest02(); new Thread(()->test.te()).start(); // test::teTryLock lambda写法 new Thread(test::teTryLock).start(); } private void teTryLock() { boolean res = false; try { // 尝试获取 5秒钟获取不到就结束 res = lock.tryLock(5,TimeUnit.SECONDS); if (res) { System.out.println("teTryLock获取到锁了,执行获取到锁的代码"); } else{ System.out.println("teTryLock没有获取到锁 执行没有获取到锁的代码"); } } catch (Exception e) { e.printStackTrace(); } finally { // 如果获取到锁了 再释放 if (res) { lock.unlock(); } } } public void te(){ try { // 获取锁 lock.lock(); System.out.println("te获取到锁执行代码!"); Thread.sleep(10000); } catch (Exception e) { e.printStackTrace(); } finally { // 一定注意 在finally中释放锁 lock.unlock(); System.out.println("te释放锁!"); } } }
输出结果:
te获取到锁执行代码!
teTryLock没有获取到锁 执行没有获取到锁的代码
te释放锁!
1.3 lockInterruptibly
synchronized 如果开始等待是不能结束的
但是Lock使用lockInterruptibly 可以被中断 在异常捕获里捕获异常 然后做一些后置处理
public class LockTest03 { // 新建锁 Lock lock = new ReentrantLock(); public static void main(String[] args) throws InterruptedException { // 测试 LockTest03 test = new LockTest03(); new Thread(test::te).start(); Thread thread = new Thread(test::teLockInterruptibly); thread.start(); Thread.sleep(3000); thread.interrupt(); } private void teLockInterruptibly() { boolean res = true; try { // 尝试获取 5秒钟获取不到就结束 lock.lockInterruptibly(); System.out.println("获取到锁··"); } catch (InterruptedException e) { //没有正常获取锁 被Interrupt了 res = false; System.out.println("InterruptedException:被打断了 做一些其他处理"); } finally { // 如果没被打断 是正常获取锁的(理论上是,也可能有其他异常) if(res) { lock.unlock(); } } } public void te(){ try { // 获取锁 lock.lock(); System.out.println("te获取到锁执行代码!"); // te 方法睡死过去了 Thread.sleep(10000000); } catch (Exception e) { e.printStackTrace(); } finally { // 一定注意 在finally中释放锁 lock.unlock(); System.out.println("te释放锁!"); } } }
1.4 公平锁
synchronized是非公平锁 后来的也可能会先获取到锁
Lock锁默认也是非公平锁
非公平锁是什么样的?
用不要脸的小强来做比喻,假设有10个人在排队买饼,小强这时候也来买饼了,不要脸的他直接跑第一个位置,这时候如果正有人在选饼,那他就灰溜溜的走了,如果上一个人刚好买完,下一个人还没有开始选,那不要脸的小强就会趁着这个间隙直接跟老板选饼. 这样对于后边排队的是不公平的 所以称为不公平锁
在ReentrantLock的实现中,不要脸的小强会尝试好几次,最后都失败的话他才会去队尾排队
Lock可以实现公平锁:公平锁就是lock的时候会先去排队队列里边看看,有没有人在排队,有的话站后边去,可以看我写过的AQS ,用公平锁做的举例 讲到了源码层
注意:公平锁不是完全公平,公平锁只是会检查队列里有没有人排队,如果没有自己去申请锁,如果有自己去排队,去检查有没有人排队的时候可能会出现不公平(地铁一个人一大步窜你前边了),进队列的时候也可能会出现不公平(地铁一个人一大步窜你前边了)
Lock lock = new ReentrantLock(true); // true表示公平
到此这篇关于Java中的锁ReentrantLock详解的文章就介绍到这了,更多相关ReentrantLock详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
PowerJob的DatabaseMonitorAspect源码流程
这篇文章主要为大家介绍了PowerJob的DatabaseMonitorAspect源码流程解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2024-01-01Java 中Comparable和Comparator区别比较
本文,先介绍Comparable 和Comparator两个接口,以及它们的差异;接着,通过示例,对它们的使用方法进行说明2013-09-09springmvc学习笔记-返回json的日期格式问题的解决方法
本篇文章主要介绍了springmvc学习笔记-返回json的日期格式问题的解决方法,解决了日期格式的输出,有兴趣的可以了解一下。2017-01-01Mybatis中一对多(collection)和一对一(association)的组合查询使用
这篇文章主要介绍了Mybatis中一对多(collection)和一对一(association)的组合查询使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-12-12基于Java的Spring框架来操作FreeMarker模板的示例
这篇文章主要介绍了基于Java的Spring框架来操作FreeMarker模板的示例,讲到了用于进行web模板文件的插值操作等例子,需要的朋友可以参考下2016-03-03
最新评论