ReentrantLock重⼊锁

ReentrantLock

重⼊锁可以完全替代synchronized关键字。在JDK 5 . 0 的早期版本中,重⼊锁的性能远远好于synchronized,但从JDK6 . 0 开始,JDK在synchronized上做了⼤量的优化,使得两者的性能差距并不⼤。重⼊锁对逻辑控制的灵活性要远远好于synchronized。

⽅法

  • void lock():获得锁,如果锁已经被占⽤,则等待。
  • void lockInterruptibly():获得锁,但优先响应中断。
  • boolean tryLock():尝试获得锁,如果成功,返回true;如果失败则返回false;获得不到锁,则不进
  • ⾏等待,⽴即返回。
  • boolean tryLock(long time, TimeUnit unit):在给定时间内尝试获得锁。
  • boolean isHeldByCurrentThread():判断担⼼线程是否持有锁。
  • void unlock():释放锁。

下⾯是使⽤重⼊锁的简单示例:

之所以称之为 重⼊锁 ,就是⼀个线程允许反复进⼊。当然,这⾥的反复仅仅局限于⼀个线程;如果同⼀个线程多次获锁,那么在释放锁的时候,也必须释放相同次数。如果释放锁的次数多,那么会得到⼀个 java.lang.IllegalMonitorStateException 异常,反之,如果释放锁的次数少,那么相当于线程还持有这个锁。如下所示:

 

lockInterruptibly()

如果使⽤synchronized,要么获得锁,要么保持等待。⽽如果使⽤了重⼊锁,则提供了另⼀种可能,那就是线程可以被中断。也就是在等待锁的过程中,程序可以根据需要取消对锁的请求。即: 如果⼀个线程正在等待锁,那么它依然可以收到⼀个通知,被告知⽆须再等待,可以停⽌⼯作了 。可以很好的应对死锁问题。示例如下所示: 

tryLock(long time, TimeUnit unit)

除了等待外部通知之外,要避免死锁还有另外⼀种⽅式,就是 限时等待 。以下⾯为例,线程尝试获得锁,如果没有获得锁,则等待5 秒钟。如果 5 秒钟之后依然没有获得锁,则返回false,表示获得锁失败。
tryLock()⽅法也可以不带参数直接运⾏。在这种情况下,当前线程会尝试获得锁,如果锁并未被其他线程占⽤,则申请锁会成功,并⽴即返回true。如果锁被其他线程占⽤,则 当前线程不会进⾏等待,⽽是⽴即返回false 。这种模式不会引起线程等待,因此也不会产⽣死锁。

公平锁和⾮公平锁 

在⼤多数情况下,锁的申请都是⾮公平锁。系统只是会从这个锁的等待线程中随机选择⼀个。类似⼤家买票不去排队,乱哄哄的围在售票窗⼝前,售票员忙得焦头烂额,也顾不及谁先谁后,随便找⼀个⼈出票就完事⼉了。
当⼊参为true时,则采⽤公平锁⽅式。要求系统维护⼀个有序队列,因此公平锁的实现成本⽐较⾼,性能相对也⾮常低下。因此,默认情况下,锁是⾮公平的。如果没有特别的需求,也不需要使⽤公平锁。

参考资料:Java并发编程AQS-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值