`
marb
  • 浏览: 418776 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ReentrantLock可重入锁的使用场景

    博客分类:
  • JAVA
 
阅读更多

摘要

从使用场景的角度出发来介绍对ReentrantLock的使用,相对来说容易理解一些。

场景1:如果发现该操作已经在执行中则不再执行(有状态执行)

a、用在定时任务时,如果任务执行时间可能超过下次计划执行时间,确保该有状态任务只有一个正在执行,忽略重复触发。
b、用在界面交互时点击执行较长时间请求操作时,防止多次点击导致后台重复执行(忽略重复触发)。

以上两种情况多用于进行非重要任务防止重复执行,(如:清除无用临时文件,检查某些资源的可用性,数据备份操作等)

1 private ReentrantLock lock = new ReentrantLock();
01                 if (lock.tryLock()) {  //如果已经被lock,则立即返回false不会等待,达到忽略操作的效果 
02  
03                     try {
04  
05                        //操作
06  
07                     finally {
08                         lock.unlock();
09                     }
10  
11                 }

 

 

 

 

场景2:如果发现该操作已经在执行,等待一个一个执行(同步执行,类似synchronized)

这种比较常见大家也都在用,主要是防止资源使用冲突,保证同一时间内只有一个操作可以使用该资源。
但与synchronized的明显区别是性能优势(伴随jvm的优化这个差距在减小)。同时Lock有更灵活的锁定方式,公平锁与不公平锁,而synchronized永远是公平的

这种情况主要用于对资源的争抢(如:文件操作,同步消息发送,有状态的操作等)

ReentrantLock默认情况下为不公平锁

 

1 private ReentrantLock lock = new ReentrantLock(); //参数默认false,不公平锁
2 private ReentrantLock lock = new ReentrantLock(true); //公平锁
1 try {
2     lock.lock(); //如果被其它资源锁定,会在此等待锁释放,达到暂停的效果
3  
4    //操作
5  
6 finally {
7     lock.unlock();
8 }

不公平锁与公平锁的区别:

公平情况下,操作会排一个队按顺序执行,来保证执行顺序。(会消耗更多的时间来排队)
不公平情况下,是无序状态允许插队,jvm会自动计算如何处理更快速来调度插队。(如果不关心顺序,这个速度会更快)

 

场景3:如果发现该操作已经在执行,则尝试等待一段时间,等待超时则不执行(尝试等待执行)

这种其实属于场景2的改进,等待获得锁的操作有一个时间的限制,如果超时则放弃执行。
用来防止由于资源处理不当长时间占用导致死锁情况(大家都在等待资源,导致线程队列溢出)。

01                 try {
02                     if (lock.tryLock(5, TimeUnit.SECONDS)) {  //如果已经被lock,尝试等待5s,看是否可以获得锁,如果5s后仍然无法获得锁则返回false继续执行
03  
04  
05                         try {
06  
07  
08                             //操作
09  
10  
11                         finally {
12                             lock.unlock();
13                         }
14  
15  
16                     }
17                 catch (InterruptedException e) {
18                     e.printStackTrace(); //当前线程被中断时(interrupt),会抛InterruptedException                 
19                 }
20  
21   
22   
23  <div>
24  
25  
26   
27   
28  </div>
29 <span></span>

 

场景4:如果发现该操作已经在执行,等待执行。这时可中断正在进行的操作立刻释放锁继续下一操作。

synchronized与Lock在默认情况下是不会响应中断(interrupt)操作,会继续执行完。lockInterruptibly()提供了可中断锁来解决此问题。(场景2的另一种改进,没有超时,只能等待中断或执行完毕)

这种情况主要用于取消某些操作对资源的占用。如:(取消正在同步运行的操作,来防止不正常操作长时间占用造成的阻塞)

1 try {
2     lock.lockInterruptibly();
3     //操作
4  
5 catch (InterruptedException e) {
6     e.printStackTrace();
7 finally {
8     lock.unlock();
9 }

 

可重入概念

若一个程序或子程序可以“安全的被并行执行(Parallel computing)”,则称其为可重入(reentrant或re-entrant)的。即当该子程序正在运行时,可以再次进入并执行它(并行执行时,个别的执行结果,都符合设计时的预期)。可重入概念是在单线程操作系统的时代提出的。

分享到:
评论

相关推荐

    Java可重入锁的实现原理与应用场景

    Java可重入锁的实现原理与应用场景 Java可重入锁是一种特殊的锁机制,允许同一个线程在不同的层次上获取同一个锁,而不会发生死锁或阻塞的情况。这种锁机制广泛应用于多线程编程中,用于解决线程之间的同步问题。 ...

    ReentrantLock源码的使用问题详解.docx

    ReentrantLock,可重入锁,是Java并发编程中一个重要的锁实现,它提供了比synchronized更高级别的控制能力,包括公平性和非公平性选择。本文将深入探讨ReentrantLock的原理,特别是其公平锁与非公平锁的概念,以及...

    Java源码解析之可重入锁ReentrantLock

    ReentrantLock是一个可重入锁,在ConcurrentHashMap中使用了ReentrantLock。它是一个可重入的排他锁,它和synchronized的方法和代码有着相同的行为和语义,但有更多的功能。 ReentrantLock是被最后一个成功lock锁...

    教你完全理解ReentrantLock重入锁

    ReentrantLock支持重入性,意味着一个线程可以多次进入同一段被该锁保护的代码,只要这个线程还没有释放这个锁。这种特性对于某些复杂并发场景特别有用。 在ReentrantLock中,重入性是通过维护每个锁的同步状态(即...

    redislock-基于redis的分布式可重入锁

    在Java中,ReentrantLock是内置的可重入锁,而在分布式环境中,我们可以利用Redis的特性来构建类似的机制。 Redis提供了`SETNX`(Set if Not eXists)命令,可以用于原子性地设置一个键的值,如果键不存在的话。这...

    各种锁汇总,乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁、行级锁等

    4. **可重入锁**:可重入锁允许一个线程获取同一资源的多次锁定,如Java的`synchronized`和`ReentrantLock`。这样可以避免死锁,当一个线程已经持有锁,尝试获取同一锁时,它能再次获得。 5. **互斥锁(Mutex)**:...

    Lock、Synchoronized和ReentrantLock的使用

    Lock、Synchronized 和 ReentrantLock 是 Java 中三种常用的同步机制,每种机制都有其特点和使用场景。下面对这三种机制进行详细的分析和比较。 一、Synchronized Synchronized 是 Java 中最基本的同步机制,它...

    ReentrantLock 实现原理 1

    ReentrantLock 的实现原理基于 AQS(AbstractQueuedSynchronizer),是一个重入锁,允许一个线程反复地获取锁而不会出现自己阻塞自己的情况。 ReentrantLock 的构造方法可以指定锁的类型,包括公平锁和非公平锁。...

    简单聊聊Synchronized和ReentrantLock锁.docx

    相比之下,ReentrantLock(可重入锁)是Java并发包java.util.concurrent.locks中的一个类,提供了更细粒度的锁控制。ReentrantLock允许显式获取和释放锁,并且支持更丰富的锁原语,如公平锁、非公平锁、可中断锁、...

    java ReentrantLock详解.docx

    相较于`synchronized`,`ReentrantLock`的主要优势在于其灵活性、可重入性和可中断性。 1. **可重入性**: 无论是`synchronized`还是`ReentrantLock`,都支持可重入特性。这意味着一个线程可以多次获取同一锁,...

    Java多线程高并发篇(一)--重入锁

    在Java多线程高并发编程中,重入锁(ReentrantLock)是一个至关重要的概念,它提供了比Java内置锁(synchronized)更细粒度的控制,并且具有更高的可读性和可扩展性。本篇文章将深入探讨重入锁的相关知识点。 首先...

    Java多线程 ReentrantLock互斥锁详解

    ReentrantLock的主要特点是可以重入,即一个线程可以多次获得锁,而不需要释放锁。这种机制可以避免死锁的出现。 ReentrantLock的使用场景非常广泛,一般用于解决多线程访问共享资源的问题。在Java中,...

    Java并发编程之显示锁ReentrantLock和ReadWriteLock读写锁

    ReentrantLock是一个可重入的锁,这意味着一个线程可以多次获取同一锁,这与synchronized内置锁的行为相同。然而,与内置锁不同的是,使用ReentrantLock需要显式调用`lock()`和`unlock()`方法来获取和释放锁,这增加...

    多线程(11)ReentrantLock公平锁与非公平锁(修改)1

    在Java并发编程中,`ReentrantLock`是一个可重入的互斥锁,相比`synchronized`提供了更细粒度的控制以及更丰富的特性。`ReentrantLock`的公平性和非公平性是其重要的特性之一。在上述代码中,我们创建了一个`...

    JUC最详细思维导图,一次了解读写锁,可重入锁,Cas原理,volatile 关键字原理

    可重入锁,如`java.util.concurrent.locks.ReentrantLock`,允许一个线程多次进入同一锁定区域,这在递归方法中尤其有用。当线程试图重新进入已被其持有的锁时,它不会被阻塞。这与传统的非可重入锁形成对比,后者...

    Java多线程之ReentrantLock与Condition - 平凡希 - 博客园1

    Java中的`ReentrantLock`是Java并发包`java.util.concurrent.locks`中的一个高级锁机制,它是可重入的互斥锁,具有与`synchronized`关键字相似的同步性,但提供了更多的灵活性和控制功能。本篇文章将深入探讨`...

    Java中ReentrantLock的使用.docx

    ReentrantLock的名字来源于它的可重入性,这意味着一个线程可以多次获取同一把锁,这在递归调用中特别有用。无论是ReentrantLock还是synchronized,它们都是可重入锁。 ReentrantLock在Java 5.0引入,最初因其性能...

    第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock()1

    ReentrantLock是由Java提供的可重入互斥锁,支持公平锁和非公平锁两种模式。非公平锁的特性是获取锁的线程不论先后,都有机会获得锁,而公平锁则遵循先进先出的原则,保证线程按照请求锁的顺序进行。 2. **...

    ReentrantLock与synchronized

    - 它是可重入的,即一个线程可以多次获取同一锁,不会发生死锁。 2. **使用方式**: - `ReentrantLock`提供`lock()`和`unlock()`方法来加锁和解锁。 - 支持公平锁(通过构造函数传入`true`)和非公平锁(默认)...

    ReentrantLock源码分析

    - 是,则将锁的重入次数加1,并返回true。 - 否,则返回false。 #### 总结 ReentrantLock通过AQS提供了强大的锁管理能力,尤其在非公平锁模式下,即使在高并发场景下也能表现出良好的性能。通过对上述流程的分析...

Global site tag (gtag.js) - Google Analytics