什么情况下会使用到ReentrantLock的重入功能?

假设我们现在去买水果,创建一个买水果的类,里面默认有500块。如下:

public class BuyFruit {
    int money = 500;
}

然后我们设置两个买水果的方法,如下:

public class BuyFruit {
    int money = 500;

    public void buyApple() {
        money -= 5;
    }

    public void buyOrange() {
        money -= 4;
    }
}

我们知道,这样子的加减操作并不是线程安全的(如果不了解,可以先搜索一下“i++是线程安全的吗”等类似问题),所以我们需要加锁,并且使用了ReentrantLock这个可重入锁,如下:

public class BuyFruit {
    int money = 500;
    ReentrantLock lock = new ReentrantLock();

    public void buyApple() {
        lock.lock();
        money -= 5;
        lock.unlock();
    }

    public void buyOrange() {
        lock.lock();
        money -= 4;
        lock.unlock();
    }
}

现在我们可以很好地购买苹果和橙子了,也没有并发问题存在。

水果店推出了一套新购买方案,购买水果的时候也可以购买水果盒子,水果店免费帮助包装,并且水果价钱便宜1块,另外如果只是想购买水果盒子,水果店也是可以出售的。这样我们就可以有了下面的代码:

public class BuyFruit {
    int money = 500;
    ReentrantLock lock = new ReentrantLock();

    public void buyApple() {
        lock.lock();
        money -= 5;
        lock.unlock();
    }

    public void buyOrange() {
        lock.lock();
        money -= 4;
        lock.unlock();
    }

    public void buyBox() {
        lock.lock();
        money -= 2;
        lock.unlock();
    }

    public void buyAppleWithBox() {
        lock.lock();
        buyApple();
        buyBox();
        money += 1;
        lock.unlock();
    }

    public void buyOrangeWithBox() {
        lock.lock();
        buyOrange();
        buyBox();
        money += 1;
        lock.unlock();
    }
}

可以发现buyAppleWithBox()和buyOrangeWithBox()里面出现了锁重入。

假设锁不支持重入,那会出现什么?那么线程就会在第二次lock.lock()的时候获取不到锁而阻塞,而想要释放锁,又需要该线程执行下去,这样就死锁了,所以可重入锁的使用场景就来了。

当然,上面的需求也可以使用原子类AtomicInteger来实现,这里仅仅只是想说明一下,随着需求的增加,有时候锁的重入是难以避免的,所以支持重入是锁的一项重要功能。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值