JUC高并发编程(09) -- 多线程锁 -- 可重入锁

本文介绍了Java中的可重入锁,包括其核心概念和应用场景。通过示例代码展示了synchronized关键字和ReentrantLock如何实现可重入锁,解释了可重入锁的目的是防止死锁,允许同一线程多次进入已锁定的代码段。同时,文章通过代码演示了可重入锁的使用,包括正常情况和可能导致StackOverflowError的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JUC高并发编程

六、多线程锁

6.3)可重入锁

核心问题场景:当一个线程获得当前实例的锁lock,并且进入了方法A,该线程在方法A没有释放该锁的时候,是否可以再次进入使用该锁的方法B?

不可重入锁:在方法A释放锁之前,不可以再次进入方法B

可重入锁:在方法A释放该锁之前,可以再次进入方法B

不可重入锁:

当线程在访问A方法的时候,获取的A方法的锁,在A方法锁释放之前不能够访问其他方法(如方法B)的锁。

不可重入锁模型:{}{}{}{}{}都是独立的访问每一个方法,加锁 - 释放;加锁 - 释放。。。

可重入锁:

当线程在访问A方法的时候,获取A方法的锁,然后访问B方法获取B方法的锁,并计数加1,以此类推可以访问完了以后依次解锁。

可重入锁模型:{{{{}}}} 每次都可访问另一个方法,且加锁计数器加1,完全释放锁为计数器等于0

可重入锁,是指同一个线程可以重入上锁的代码段,不同的线程进入则需要进行阻塞等待。

Java的可重入锁有:reentrantLock(显式的可重入锁)【手动上锁解锁】、synchronized(隐式的可重入锁)【自动上锁解锁】

可重入锁诞生的目的:防止死锁,导致同一个线程不可重入上锁代码段,目的就是让同一个线程可以重新进入上锁代码段

6.3.1)synchronized实现可重入锁

synchronized实现可重入锁代码示例:

//synchronized实现可重入锁代码示例
public class SyncLockDemo {
    public static void main(String[] args) {
        // synchronized实现可重入锁
        Object o = new Object();
        new Thread(() -> {
            synchronized (o) {
                System.out.println(Thread.currentThread().getName() + " 外层");
​
                synchronized (o) {
                    System.out.println(Thread.currentThread().getName() + " 中层");
​
                    synchronized (o) {
                        System.out.println(Thread.currentThread().getName() + " 内层");
                    }
                }
            }
        }, "t1").start();
    }
}

输出:在外层的锁释放前,仍然可以进入上锁的中层和内层代码块

t1 外层

t1 中层

t1 内层

可重入锁又称递归锁,递归锁代码示例:

public class SyncLockDemo1 {
    public synchronized void add() {
        add();
    }
​
    public static void main(String[] args) {
        new SyncLockDemo1().add();
    }
}

输出:

Exception in thread "main" java.lang.StackOverflowError

at com.study.sync.SyncLockDemo1.add(SyncLockDemo1.java:12)

6.3.2)Lock 实现可重入锁

Lock实现可重入锁代码示例:

// Lock实现可重入锁代码示例
public class SyncLockDemo2 {
    public static void main(String[] args) {
        //Lock演示可重入锁
        Lock lock = new ReentrantLock();
        //创建线程
        new Thread(() -> {
            try {
                //上锁
                lock.lock();
                System.out.println(Thread.currentThread().getName() + " 外层");
​
                try {
                    //上锁
                    lock.lock();
                    System.out.println(Thread.currentThread().getName() + " 内层");
                } finally {
                    //释放锁
                    lock.unlock();
                }
            } finally {
                //释放做
                lock.unlock();
            }
        }, "t1").start();
​
        //创建新线程
        new Thread(() -> {
            lock.lock();
            System.out.println("aaaa");
            lock.unlock();
        }, "aa").start();
    }
}

输出:lock 需要手动上锁和解锁,如果不解锁,将会一直卡在该线程中,无法继续执行后面的线程创建操作

t1 外层

t1 内层

aaaa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值