显示锁-ReentrantLock

本文探讨了ReentrantLock作为Lock接口的实现,与Synchronized的异同,包括可重入性、公平与非公平锁特性、吞吐量比较以及何时选择ReentrantLock。ReentrantLock提供了更多的灵活性但需手动管理,而Synchronized有自动释放机制,避免死锁。
摘要由CSDN通过智能技术生成

1、概念:ReentrantLock实现了Lock接口,并且提供了和Synchronized相同的互斥性和内存可见性。另外,ReentrantLock并不是用来代替Synchronized的,而是当Synchronized的加锁机制不合适时,作为一种可选择的高级功能。

2、对比Synchronized

  • 皆可重入:两者都提供了可重入的语义。
  • ReentrantLock更加灵活:
    (1)ReentrantLock可以终止一个正在等待锁的线程。
    (2)设置轮询锁,尝试获取锁,设置一定次数,轮询该次数后依然没有获取到锁,则放弃获取。
    (3)设置定时锁,在规定时间内去获取锁,超过这个时间,则放弃获取。
  • ReentrantLock必须显示的加锁和释放锁,如果忘记在finally中忘记释放锁,那么就相当于埋下了一颗定时炸弹,因此具有一定的“危险性”;Synchronized在发生异常时会自动释放锁,避免了异常时的死锁。
  • 吞吐量:Java5.0时,ReentrantLock性能会好很多;到了Java6.0,两者的效果差不多。

3、公平锁和非公平锁

        公平锁确保被阻塞的线程都能够获取到锁,避免了线程获取锁的饥饿现象;但是在激烈竞争的情况下,线程从内核态转变为用户态存在着严重的延迟,此时会带来性能的影响。

        非公平锁则是让线程可以”插队“,在非公平锁的情况下,新来的线程只有在锁被别的线程持有时,才会进入队列,不然不会进入队列,而是立即参与竞争,如果竞争成功,则省去了线程状态切换的开销,这说明了某些情况下,非公平锁比公平锁性能要好。但是,非公平锁会出现饥饿现象。

        Synchronized是非公平锁。

        ReentrantLock可以自主选择,默认是非公平锁;如果创建时传入true,则是公平锁。

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

4、抉择

        只有在内置锁无法满足要求的情况下,才应该去考虑ReentrantLock,ReentrantLock作为一种高级的备选方案,选择它的原因是因为它的高级功能。如若不然,优先考虑Synchronized。

5、原理

  1. 锁的竞争,通过互斥变量,使用CAS机制实现;没有竞争到锁的线程使用AbstractQueuedSynchronizer线程同步器来存储,同步器底层通过双向链表实现,当锁被释放之后,会从AQS队列头部唤醒一个线程。
  2. 锁重入原理:AQS里面有一个成员变量来保存当前获取到锁的的线程,如果该线程再次获取锁,那么就可以直接增加锁的重入次数,不会走竞争逻辑。
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: synchronized和reentrantlock都是Java中用于实现线程同步的机制。 synchronized是Java中最基本的同步机制,它可以用于方法或代码块级别的同步。当一个线程进入synchronized代码块时,它会尝试获取,如果已经被其他线程持有,则该线程会被阻塞,直到被释放。synchronized机制是Java中最常用的同步机制之一,但它有一些限制,例如无法中断正在等待的线程,也无法尝试获取而不阻塞。 reentrantlockJava中另一种同步机制,它提供了更多的灵活性和控制。与synchronized不同,reentrantlock可以中断正在等待的线程,也可以尝试获取而不阻塞。此外,reentrantlock还提供了一些高级功能,例如公平和可重入。但是,reentrantlock的使用比synchronized更复杂,需要手动获取和释放,并且需要注意避免死等问题。 总的来说,synchronized是Java中最基本的同步机制,适用于大多数情况。而reentrantlock则提供了更多的灵活性和控制,适用于一些特殊的场景。 ### 回答2: synchronized和ReentrantLockJava中用于实现线程同步的两种机制。 synchronized是Java中最基本的线程同步机制,它使用了内置的监视器(也称为对象或互斥)来控制线程的访问。synchronized关键字可以用于方法或代码块,并且是隐式。当线程执行到synchronized关键字时,会自动获取,执行完后会自动释放。synchronized关键字确保了在同一时间只有一个线程可以访问被定的代码或方法,从而保证了线程的安全性。然而,synchronized关键字也有一些缺点,比如无法获得时会一直阻塞等待和释放。 ReentrantLockJava中的另一种线程同步机制,它是通过显示来实现的。ReentrantLock提供了更灵活的定操作,相比于synchronized,它具有更多的特性。ReentrantLock可以使用lock()和unlock()方法来手动加和解,这意味着我们可以更加精确地控制代码的同步性。ReentrantLock还支持可重入性,即线程可以多次获得同一个,提供了更高的灵活性。它还支持公平和非公平两种模式,可以按照先进先出的规则来选择获取的线程。此外,ReentrantLock还提供了一些高级功能,比如可中断、超时和条件变量等。 总的来说,synchronized是Java中最基本的线程同步机制,使用简单但灵活性较低。而ReentrantLock则提供了更多的功能和灵活性,但使用相对复杂一些。在实际应用中,我们可以根据具体需求来选择使用哪种线程同步机制。 ### 回答3: synchronized和ReentrantLock都是Java中用于实现线程同步的工具。 synchronized是Java中最常见的同步关键字,它可以应用在方法或代码块上。当一个线程获取到对象的synchronized时,其他线程就无法同时访问这个对象。当该线程执行完代码块或者方法,会释放,其他线程才能获得并执行。synchronized是隐式获取和释放的过程,非常方便,但也存在一些限制,例如无法中断一个正在等待获取的线程。 ReentrantLockJava中提供的一种显示,可以实现与synchronized类似的功能。与synchronized不同的是,ReentrantLock提供了更灵活和更强大的功能。它允许更细粒度的控制定的获取和释放,例如通过lock()和unlock()方法手动获取和释放,也可以通过tryLock()方法尝试获取而不需要一直等待。此外,ReentrantLock还支持公平性,即按照线程请求的顺序获取,避免产生线程饥饿现象。而synchronized则不保证公平性。 另外,ReentrantLock提供了Condition接口,可以使用newCondition()方法创建多个条件变量。条件变量可以用于线程间的通信,可以让某个线程等待特定条件满足后再继续执行,或者通知其他等待线程某个条件已经满足。 总的来说,synchronized是Java中隐式机制的实现,使用方便但功能有限;而ReentrantLock显示机制的实现,提供了更多灵活和强大的功能,但使用起来需要更细致的控制。根据具体情况需要,我们可以选择合适的同步机制来保证线程安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何怀逸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值