java并发编程 锁的可重入性

本文深入探讨了可重入锁(递归锁)的概念及其实现机制,详细解释了Java中如何通过synchronized关键字和ReentrantLock实现线程对同一锁的多次获取,避免死锁现象。

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

一、可重入锁:
本文里面讲的是广义上的可重入锁,而不是单指JAVA下的ReentrantLock。

可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层函数仍然有获取该锁的代码,但不受影响。
在Java内部,同一个线程调用自己类或父类中其他同步方法/块时不会阻碍该线程的执行,同一个线程对同一个对象锁是可重入的,同一个线程可以获取同一把锁多次,也就是可以多次重入。原因是Java中线程获得对象锁的操作是以线程为单位的,而不是以调用为单位的。
机制:每个锁都关联一个请求计数器和一个占有他的线程,当请求计数器为0时,这个锁可以被认为是unhled的,当一个线程请求一个unheld的锁时,JVM记录锁的拥有者,并把锁的请求计数加1,如果同一个线程再次请求这个锁时,请求计数器就会增加,当该线程退出同步代码块时,计数器减1,当计数器为0时,锁被释放。
在JAVA环境下 ReentrantLock 和synchronized 都是 可重入锁

下面是使用实例

public class Test implements Runnable{

    public synchronized void get(){
        System.out.println(Thread.currentThread().getId());
        set();
    }

    public synchronized void set(){
        System.out.println(Thread.currentThread().getId());
    }

    @Override
    public void run() {
        get();
    }

    public static void main(String[] args) {
        Test ss=new Test();
        new Thread(ss).start();
        new Thread(ss).start();
        new Thread(ss).start();
    }

}
查看源代码打印帮助
public class Test implements Runnable {
    ReentrantLock lock = new ReentrantLock();
    public void get() {
        lock.lock();
        System.out.println(Thread.currentThread().getId());
        set();
        lock.unlock();
    }
 
    public void set() {
        lock.lock();
        System.out.println(Thread.currentThread().getId());
        lock.unlock();
    }

    @Override
    public void run() {
        get();
    }
 
    public static void main(String[] args) {
        Test ss = new Test();
        new Thread(ss).start();
        new Thread(ss).start();
        new Thread(ss).start();
    }

}

两个例子最后的结果都是正确的,即 同一个线程id被连续输出两次。

结果如下:

Threadid: 8
Threadid: 8
Threadid: 10
Threadid: 10
Threadid: 9
Threadid: 9

可重入锁最大的作用是避免死锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值