首页 > 其他分享 >ReentrantLock-可重入锁

ReentrantLock-可重入锁

时间:2024-09-09 14:27:58浏览次数:10  
标签:重入 synchronized lock ReentrantLock 获取 finally 线程

ReentrantLock是Java并发包java.util.concurrent.locks中的一个类,它实现了Lock接口,提供了一种与Synchronized方法和语句相同的基本行为和语义的互斥锁,但具有更多的扩展功能。

主要特点

  • 可重入性
    与 synchronized 关键字一样,ReentrantLock 允许同一个线程多次获得锁,而不会发生死锁。每次成功获取锁后,锁的持有计数会增加,每次释放锁时,计数会减少。只有当计数为0时,锁才完全释放,其他线程才能获取该锁。
  • 公平性
    ReentrantLock 构造函数接受一个可选的 boolean 类型的 fairness 参数。如果设置为 true,则锁将按照请求锁的顺序(即等待时间最长的线程将优先获得锁),来授予访问权限。这有助于减少饥饿现象,但可能会降低吞吐量。如果设置为 false(默认值),则不保证任何特定的访问顺序。
  • 尝试非阻塞地获取锁
    ReentrantLock 提供了 tryLock() 方法,该方法尝试获取锁,如果锁可用,则立即返回 true,否则立即返回 false。这与 synchronized 关键字不同,后者在锁不可用时会使线程阻塞。
  • 可中断的锁获取
    ReentrantLock 支持可中断的锁获取操作,即线程在等待锁的过程中可以被中断。这通过 lockInterruptibly() 方法实现,如果当前线程在等待锁的过程中被中断,则会抛出 InterruptedException。
  • 条件变量
    与 synchronized 关键字不同,ReentrantLock 提供了条件变量(Condition),允许多个条件等待集。这允许更灵活的线程同步控制。

使用建议

  • 防止死锁
    使用try-finally语句,在调用lock()方法后,应立即使用try-finally语句来确保锁最终会被释放;
  • 考虑公平性
    如果实际应用场景中,锁的获取顺序很重要,或者希望减少饥饿现象,可以考虑将 fairness 参数设置为 true。但请注意,这可能会降低系统的吞吐量。
  • 避免过度使用
    虽然 ReentrantLock提供了比synchronized更多的功能,但过度使用可能会使代码变得复杂且难以维护。在大多数情况下,synchronized 关键字已经足够使用。

示例代码

class ReentrantLockSample {
    // 默认非公平锁
    private final ReentrantLock lock = new ReentrantLock();

    // 公平锁
    // private final ReentrantLock lock = new ReentrantLock(true);  
  
    public void method() {
        // 尝试获取锁  
        lock.lock();
        try {  
            // ... 方法体  
        } finally {  
            // 释放锁  
            lock.unlock(); 
        }  
    }  
}

在这个例子中,lock.lock() 尝试获取锁,如果锁被其他线程持有,则当前线程将阻塞,直到锁被释放。在 try 块中执行的方法体完成后,无论是否发生异常,finally 块都会确保锁被释放。

标签:重入,synchronized,lock,ReentrantLock,获取,finally,线程
From: https://www.cnblogs.com/demon001/p/18404226

相关文章

  • kimi:利用随机值验证标准库容器的读可重入性
    #include<iostream>#include<unordered_set>#include<thread>#include<mutex>#include<vector>#include<random>std::unordered_set<int>sharedSet;std::mutexsetMutex;voidinsertRandomNumbers(intcount){......
  • 【漏洞分析】Penpie 攻击事件:重入攻击构造奖励金额
    背景信息2024年9月3日,Penpie合约遭受重入攻击,攻击者在重入阶段向合约添加流动性来冒充奖励金额,从而获取合约内原有的奖励代币。资产损失高达2734万美元。2024年5月,Penpie平台新增了推出了无需许可的资产池功能,即允许Pendle上的用户可以在该平台上自建任何PT或YT......
  • ReentrantLock源码剖析
    ReentrantLock源码剖析测试案例:publicclassReentrantLockDemo{//ReentrantLocklock=newReentrantLock();//默认是非公平锁//ReentrantLocklock=newReentrantLock(true);//true:公平锁,false:非公平锁publicstaticvoidmain(String[]args){......
  • Java并发编程 - JUC介绍、JUC锁(公平锁、非公平锁、可重入锁/递归锁、自旋锁、Reentran
    Java并发编程中的java.util.concurrent(简称JUC)包提供了许多高级并发工具和类,使得开发人员能够更加方便地编写高性能的并发程序。下面将详细介绍JUC包中的一些锁相关的概念和类。JUC介绍java.util.concurrent包提供了许多高级并发工具类,包括但不限于Executor框架......
  • ReentrantLock
    可打断importjava.util.concurrent.locks.ReentrantLock;/*ReentrantLock可打断**/publicclassT{privatestaticReentrantLocklock=newReentrantLock();publicstaticvoidmain(String[]args)throwsInterruptedException{Threadthre......
  • Java Reentrantlock可重入锁原理 | 源码探究
    一、基本概念ReentrantLock是Java中提供的一个可重入互斥锁,它是java.util.concurrent.locks包中的一个接口Lock的实现类。ReentrantLock提供了比使用synchronized关键字更强大的锁定机制,例如 公平锁 和 非公平锁 选择、尝试锁定、可中断锁定等。ReentrantLock......
  • ReentrantLock的阻塞性、可中断性
    结论:lock()如果没有获取到锁,会一直阻塞并尝试获取锁,直到获取到锁。lock()获取到锁之前,其他线程不可以中断该线程。因为线程Thread如线程t2的interrupt方法,想要中断线程,但不会真的中断,只会把t2的中断标志改变,所以线程t2还会继续运行。lockInterruptibly()获取到锁之前,其他线......
  • 可重入锁ReentrantLock
    ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,支持重入性,表示能够对共享资源重复加锁,即当前线程获取该锁后再次获取不会被阻塞。要想支持重入性,就要解决两个问题:在线程获取锁的时候,如果已经获取锁的线程是当前线程的话则直接再次获取成功......
  • Java中的ReentrantLock详解
    Java中的ReentrantLock详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在Java编程中,多线程同步是一个常见的需求。为了保证多个线程对共享资源的安全访问,Java提供了多种锁机制,其中ReentrantLock是一个重要的工具。本文将详细介绍ReentrantLock的使用,......
  • Java并发编程 - ReentrantLock
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录一、ReentrantLock是什么?二、基本使用2.1基本语法2.2经典案例-取款问题2.2.1不加锁情况2.2.2使用ReentrantLock三、特性3.1可重入3.2可打断3.2.1无竞争3.2.2有竞争-获取不到锁3.3.3......