首页 > 编程语言 >java~理解可重入锁

java~理解可重入锁

时间:2023-06-21 09:55:41浏览次数:42  
标签:重入 java synchronized 持有 获取 死锁 理解 线程

在Java中,可重入锁(Reentrant Lock)是一种同步机制,允许线程在持有锁的情况下再次获取该锁,而不会被自己所持有的锁所阻塞。也就是说,一个线程可以多次获得同一个锁,而不会出现死锁的情况。

可重入锁在多线程编程中非常有用,它允许线程在访问共享资源时多次获取锁,而不会引发死锁问题。当一个线程第一次获取锁后,会在内部维护一个计数器,每次成功获取锁后计数器加1,每次释放锁后计数器减1。只有当计数器归零时,锁才会完全释放,其他线程才有机会获取该锁。

可重入锁的一个重要特性是,如果一个线程已经持有了锁,那么它可以重复地获得该锁,而不会被自己所持有的锁所阻塞。这种机制可以避免了死锁的发生,因为线程可以在需要的时候重复获取锁,而不会被自己所持有的锁所阻塞住。

可重入锁的实现在Java中有多种选择,其中最常用的是ReentrantLock类。使用可重入锁可以通过以下步骤:

  1. 创建可重入锁对象:可以使用ReentrantLock类的构造方法创建一个可重入锁对象,例如:

    ReentrantLock lock = new ReentrantLock();
    
  2. 获取锁:使用lock()方法获取锁,如果锁不可用,则当前线程将被阻塞,直到获取到锁为止,例如:

    lock.lock();
    
  3. 执行需要保护的临界区代码:获取到锁后,执行需要保护的临界区代码。

  4. 释放锁:使用unlock()方法释放锁,确保在临界区代码执行完毕后释放锁,例如:

    lock.unlock();
    

使用可重入锁的好处是它提供了更灵活的同步机制,可以方便地控制线程对共享资源的访问。但是需要注意的是,在使用可重入锁时,确保每次获取锁都有相应的释放操作,以避免造成死锁或资源泄漏的问题。

synchronized是可重入锁吗

是的,Java中的synchronized关键字实际上是一种可重入锁。当一个线程获得了一个对象的锁之后,它可以多次地进入由这个对象的锁保护的synchronized代码块,而不会被自己所持有的锁所阻塞。

可重入性是Synchronized的一个重要特性,它使得线程可以在持有锁的情况下再次获取相同锁,而不会产生死锁。当一个线程尝试进入一个由synchronized保护的代码块时,会先尝试获取锁,如果锁已被其他线程持有,该线程会进入阻塞状态,等待锁的释放。然而,如果该线程已经持有了同一个锁,它可以直接进入临界区,而不会被自己所持有的锁所阻塞。

下面是一个示例,展示了synchronized的可重入性:

class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
        anotherMethod();
    }

    public synchronized void anotherMethod() {
        // 可以再次获取相同的锁
        count++;
    }
}

在上述示例中,increment()方法和anotherMethod()方法都使用了synchronized关键字来实现同步。当一个线程调用increment()方法时,它会获取到Counter对象的锁,并执行count++操作,然后调用anotherMethod()方法。由于anotherMethod()方法也使用了相同的锁,线程可以再次获取该锁并执行相应的操作。

需要注意的是,可重入性是在同一个锁对象上实现的,即线程需要持有同一个锁对象才能再次进入临界区。如果线程尝试在不同的锁对象上再次获取锁,它仍然会被阻塞,因为每个锁对象是独立的。

标签:重入,java,synchronized,持有,获取,死锁,理解,线程
From: https://www.cnblogs.com/lori/p/17495511.html

相关文章

  • 【后端面经-java】java线程池满的处理策略
    目录1.线程池介绍1.1基本作用1.2处理流程1.3线程池大小设置1.4线程池参数2.线程池满的处理策略2.1默认--拒绝策略handler3.参考资料1.线程池介绍1.1基本作用对多个线程使用的资源进行集中管理。降低资源消耗:复用线程,降低线程创建和销毁造成的消耗;线程资源管理......
  • Java基础之“Double类型,保留两位小数,避免因小数过长导致乱码问题”
    保留两位小数方案一DoubletotalSaleAmount=4.174558045899999E7;DecimalFormatdf=newDecimalFormat("#.##");System.out.println("df.format(totalSaleAmount)="+df.format(totalSaleAmount));方案二DoubletotalSa......
  • java~字节码操作Javassist
    Javassist是一个开源的Java字节码操作库,它提供了一组简单而强大的API,用于在运行时修改和生成Java字节码。Javassist的名称是"JavaProgrammingAssistant"的缩写,它的目标是简化对字节码的操作,使开发人员能够更轻松地实现动态代码生成和修改。Javassist的主要特点包括:简单易用:J......
  • javaee项目
       ......
  • java递归创建目录
    importjava.io.File;publicclassCreateDirectory{publicstaticvoidmain(String[]args){Stringpath="D:\\heap\\d\\c\\e";createDirectory(path);}publicstaticvoidcreateDirectory(Stringpath){......
  • java-http携带json参数访问接口
    一个接收map的接口@RequestMapping("kkw")publicStringkkw(@RequestBodyMap<String,Object>map){if(map!=null){System.out.println(JSONObject.toJSONString(map));;}return"success";}pac......
  • java调用pmml算法模型
    ==背景==项目需要调用算法模型,用于优化工艺参数。 ==思路==根据团队不具备算法训练能力的特点,技术上采用“训练与使用分离”的策略,即:模型训练寻找第三方渠道,将训练好的算法模型导出pmml文件,然后通过java调用模型文件。 ==代码样例==【准备模型】找朋友要了了一个测试用......
  • 简单记录下 Spring Boot 使用虚拟线程Virtual Threads(Java的协程)的方法
    在之前的文章中,简单描述了将springboot2.x升级springboot3.1的版本的过程。本文将简单介绍如何在spring中引入虚拟线程,在文章最后会放上一些关于虚拟线程的官方参考资料。JDK22会引来重要特性,VirtualThreads也就是协程功能。与主流的async、await方案(C#、JS等语言)相比......
  • 为什么很多人说不建议学JAVA,说很难找到工作?
    个人感觉这个观点有点片面。虽然国内的IT市场已经变得越来越竞争激烈,但Java作为一种应用广泛的编程语言仍然非常受欢迎。Java可以应用于Web开发、移动开发、大数据处理等多个领域,具有广泛的用途和良好的生态圈。因此,在Java领域拥有一定技能的人才仍然有很多岗位可以选择。如果......
  • Java的7种位运算符
    位运算符在Java语言中,提供了7种位运算符,分别是按位与(&)、按位或(|)、按位异或(^)、取反(~)、左移(<<)、带符号右移(>>)和无符号右移(>>>)操作符语义描述运算规则&  按位与    二进制数据按位与操作如果两个二进制位上的数都是1,那么运算结果为1,其他情况运算结果......