Java可重入锁synchronized以及ReentrantLock详解

Java可重入锁(递归锁)

可重入锁指的是同一个线程,在外层方法获取锁后, 再进入内层方法会自动获取锁(前提,锁的是同一个对象),不会因为之前获取过没有释放导致阻塞。
Java的synchronized和ReentrantLock都是可重入锁。

可重入锁的种类

1.隐式锁(synchronized)

同步代码块-代码示例:

package multiThreads;

public class Test18 {
    public static void main(String[] args) {
        Object object = new Object();
        new Thread(() -> {
            synchronized (object) {
                System.out.println("外层代码");
                synchronized (object) {
                    System.out.println("中层代码");
                    synchronized (object) {
                        System.out.println("内层代码");
                    }
                }
            }
        }).start();
    }
}

运行结果:
在这里插入图片描述
可以看到synchronized锁定的三个代码块都执行了。

同步方法-代码示例

package multiThreads;

public class Test19 {
    public static void main(String[] args) {

        Test19 test19 = new Test19();
        test19.m1();

    }

    private synchronized void m1() {
        System.out.println("m1--------");
        m2();
    }

    private synchronized void m2() {
        System.out.println("m2--------");
        m3();
    }

    private synchronized void m3() {
        System.out.println("m3--------");
    }
}

运行结果如下:
在这里插入图片描述

2.显示锁(ReentrantLock)

ReentrantLock代码示例如下:

package multiThreads;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test18 {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        //同一个线程
        new Thread(() -> {
            lock.lock();
            try {
                System.out.println("外层代码--");
                lock.lock();
                try {
                    System.out.println("中层代码--");
                    lock.lock();
                    try {
                        System.out.println("内层代码--");
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }).start();
    }
}

运行结果:
结果

ReentrantLock的加锁解析:

第一次执行lock()方法前,reentrantLock中的sync属性值如下:
描述
其中sync是一个ReentrantLock.NonfairSync实例,state=0代表此锁还未被获取,也即此锁还未被锁定。当执行lock.lock()方法的时候,进行如下操作:
在这里插入图片描述
如果锁当前未被获取,则将state从0设置为1,且将exclusiveOwnerThread设置为当前线程。如果当前锁已被获取,则尝试获取锁,具体代码如下:
在这里插入图片描述
在这里插入图片描述
描述
通过上面的代码可以看出,当state=0的时候表示锁未被获取,当state大于0的时候表示锁已经被获取,且state值等于锁的重入次数。exclusiveOwnerThread表示锁的当前持有线程。

!!!使用显示锁ReentrantLock的时候,获取锁后一定要记得释放锁,否则可能导致后续线程无法获取此锁。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值