ReentrantLock的特点

34 篇文章 2 订阅

一 概述

自JDK5起,Java类库中新提供了java.util.concurrent包,其中的java.util.concurrent.locks.Lock接口便成了Java的另一种全新的互斥同步手段。基于Lock接口,用户能够以非块结构(Non-Block Structured)来实现互斥同步,从而摆脱了语言特性的束缚,改为在类库层面去实现同步,这也为日后扩展出不同的调度算法,不同特征,不同性能,不同语义的各种锁。

二 ReentrantLock(重入锁)

重入锁(ReenturantLock)是Lock接口最常见的一种实现,顾名思义,它与synchronized一样是可重入的,在基本用法上,ReentrantLock也与synchronized很相似,只是代码实现方法上有些区别而且,另外一个很直接的区别是synchronized为Java中的一个关键字而ReentrantLock是一个接口。

此外,ReentrantLock与synchronized相比增加了一些高级功能,主要有以下三项:等待可中断,可实现公平锁及锁可以绑定多个条件。

等待可中断:是指当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。可中断特性对处理执行时间非常长的同步块很有帮助。

公平锁:是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁;而非公平锁则不保证这一点,在锁被释放时,任何一个等待锁的线程都有机会获得锁。synchronized中的锁时非公平的,ReentrantLock在默认情况下也是非公平的,但可以通过带布尔值的构造函数要求使用公平锁不过一旦使用了公平锁,将会导致ReentrantLock的性能急剧下降,会明显影响吞吐量。

public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

锁定多个条件:是指一个ReentrantLock对象可以同时绑定多个Condition对象。在synchronized中,锁对象的wait()和它notify()或者是notifyAll()方法配合可以实现一个隐含的条件,如果要和多于一个的条件关联时候,就不得不额外添加一个锁;而ReentrantLock则无须这样做,多次调用newCondition()方法即可。

三 sychronized和ReentrantLock的性能比较

JDK5之前synchronized对性能的影响是非常明显的,为此在JDK6中专门对性能做出了优化(根据对资源的竞争激烈程度进行的, 在几乎无竞争的条件下, 会使用偏向锁, 在轻度竞争的条件下, 会由偏向锁升级为轻量级锁, 在重度竞争的情况下, 会升级到重量级锁。)

以synchronized和ReentrantLock的性能对比,Brian Goetz对两种锁在JDK5,单核处理器及双Xeon处理器环境下一组吞吐量对比的实验,结果图像如下:

由此可得,多线程环境下synchronized的吞吐量下降的非常严重,而ReentrantLock则能基本保持在同一个相对稳定的水平上,当时于其说ReentrantLock性能好,不如说当是synchronized存在非常大优化余地,在JDK6中针对synchronized加入了大量优化措施,这时候相同的测试中synchronized与ReentrantLock的性能基本基本上能够持平。

基于上述条件可知,是否可以直接使用ReentrantLock替换synchronized,答案不是,因为synchronized是在Java语法层面的同步,足够清晰,也足够简单。每个Java程序员都熟悉synchronized,当时JUC中的Lock接口则并非如此。因此在只需要基础的同步功能时,更推荐synchronized。

Lock应该确保在finally块中释放锁,否则一旦受到同步保护的代码块中抛出异常,则有可能永远不会释放持有的锁。所以程序员要自己来通过代码来保证,而使用synchronized的话则可以由java虚拟机来确保使用出现异常,锁也能自动释放。

尽管在JDK5时代ReentrantLock曾经在性能上领先过synchronized,但这已经是十多年之前的情况。从长远来看,Java虚拟机更容易针对synchronized来进行优化,因为Java虚拟机可以在线程和对象的元素据中记录synchronized中锁的相关信息,而使用JUC中的Lock的话,Java虚拟机是很难得知具体哪些锁对象是特定线程持有的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值