Synchronized重入锁

本文详细解析了重入锁的概念及其在多线程环境下的作用。通过具体代码示例,阐述了重入锁如何避免同一线程内方法调用产生的死锁问题,以及其背后的实现原理。

重入锁,指同一个线程试图获取一个已经由它自己持有的锁的一种“现象”。

譬如有一个类:

public class TestDemo{
    public synchronized void doSomething1(){
        doSomething2();
    }
    public synchronized void doSomething2(){...}
}

假设现在创建两个线程,ThreadA和ThreadB,同时调用TestDemo对象里面的方法,

//定义线程A,ThreadA
public class ThreadA extends Thread{
    private TestDemo testDemo;

    public ThreadA(TestDemo testDemo){
        this.testDemo = testDemo();
    }

    public void run(){
        testDemo.doSomething1();
        testDemo.doSomething2();
    }
}

//定义线程B,ThreadB
public class ThreadB extends Thread{
    private TestDemo testDemo;

    public ThreadA(TestDemo testDemo){
        this.testDemo = testDemo();
    }

    public void run(){
        testDemo.doSomething2();
    }
}

        当ThreadA率先获得testDemo对象锁,进入doSomething1()方法,ThreadB想要执行doSomething2()方法时,就变成了阻塞等待状态,因为doSomething1()和doSomething2()方法都是用Synchronized声明,在不同线程调用同一对象的同步代码块的这一过程很容易理解。当ThreadA执行完doSomething1()方法时,ThreadA和ThreadB就会去争夺testDemo对象锁。

        对于ThreadA,它在调用doSomrthing1()同时,里面也调用了doSomething2()方法,在没有重入锁机制时,这种情况就会变成死锁,所以,对于同一个线程来说,是允许重入锁的,同时也意味着获取锁的粒度不是“调用”,而是“线程”。

        重入锁的实现机制是怎样呢?就是为每个锁关联一个获取技术值和一个所有者线程。当计数值=0时,这个锁就被认为没有任何线程持有。当一个线程请求一个未被持有的锁时,JVM将记下锁的持有者,并且将获取值置为1,如果同一个线程再次获取这个锁,计数值将递增1,而当线程退出同步代码块时,计数值递减1,当计数值=0时,这个锁将会被释放。(这个跟调用方法时,栈的内存分配机制理解上一致。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值