实现可重入锁

实现可重入锁

今天突然想了解下 可重入锁,所以写一篇博客记录下,那么一个对象拿到锁后进入到方法后,还允许其他线程在进入吗?当不可能!那么我们来看下代码来模拟下可重入锁的场景。
在这里插入图片描述
此图可以看到方法enterAenterB都有加锁的操作
在这里插入图片描述
看下此时的main方法调用了enterA和enterB方法 ,enterA方法进入后执行myLock.lock()拿到了锁,因为Lock(锁)对象是静态的所以这时调用enterB执行myLock.lock()时不会拿到锁而是进入wait(等待)状态,又因为程序是子上而下执行这时程序处于一种尴尬状态一直等待着释放锁,但此时又不是死锁,因为死锁是两条线程互相等待。
这时可重入锁发挥作用了!

/**
 * 可重入锁
 */
public class MyReenTrantlock implements Lock {
    //单例  添加volatile为了防止虚拟机指令重排
    private static volatile MyReenTrantlock myReenTrantlock = null;
    //当前对象是否获取到锁
    private boolean lockStuta = false;
    //记录当前是否一条线程
    private Thread  presentThread = null;
    //记录可重入锁的数量
    private int reenTrantlockNum = 0;

    private MyReenTrantlock(){}
    /**
     * 判断该锁是否已被占用如果占用则让其等待
     */
    @Override
    public synchronized void lock() {
        if(lockStuta && presentThread != Thread.currentThread()){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        lockStuta = true;
        presentThread = Thread.currentThread();
        reenTrantlockNum++;
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {

    }

    @Override
    public boolean tryLock() {
        return false;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return false;
    }

    @Override
    public synchronized void unlock() {
        if(presentThread == Thread.currentThread()){
            //锁的数量减一
            reenTrantlockNum--;
            if(reenTrantlockNum == 0){
                notify();
                lockStuta = false;
            }
        }


    }

    @Override
    public Condition newCondition() {
        return null;
    }

    public static MyReenTrantlock getMyReenTrantlockBean(){
        if(myReenTrantlock == null){
            //双重检测锁
            synchronized (MyReenTrantlock.class){
                if(myReenTrantlock == null){
                    myReenTrantlock = new MyReenTrantlock();
                }
            }
        }
        return myReenTrantlock;
    }
}

在执行my.lock()时会对当前线程进行记录,下次执行my.lock()时候就会进行判断,并对可重入锁数量进行记录,就不会导致一直等待现象,如果其他线程调用的话就会进入等待状态,直到锁被释放!

本人小白,如有错误请加以指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值