ReentrantLock的一个问题

今天在回顾java并发编程时遇到一个问题,有点奇怪
代码如下

class BlockMutex {
    private Lock lock = new ReentrantLock();

    public BlockMutex() {
        lock.lock();
    }

    public void f(String name) {
        lock.lock();
        System.out.println(name+" lock acquired in f() ");
    }

}

BlockMutex是一个可能存在并发问题的资源,所以我使用lock以实现同步,创建该对象的线程在创建的时候就会持有对象锁,如构造器,在执行f()方法时候也要先申请锁

class BlockThread implements Runnable {
    //线程创建BlockThread同时就持有了blockMutex锁
    private BlockMutex blockMutex = new BlockMutex();

    public BlockMutex getBlockMutex() {
        return blockMutex;
    }

    @Override
    public void run() {
        System.out.println("waiting lock in f()");
        blockMutex.f("BlockThread");
        System.out.println("broken out of blocked call");
    }
}

这是一个Task task初始化的时候,该task就会持有锁,当task执行run方法的时候,会执行f()函数,因为BlockThread会初始化BlockMutex时就持有了BlockMutex的对象锁,而ReentrantLock是支持重入的,所以BlockThread理所应当继续执行f()方法

public static void main(String[] args) throws InterruptedException {
        BlockThread blockThread=new BlockThread();
        Thread thread = new Thread(blockThread);
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        System.out.println("main has finished ");
    }

在main函数中进行测试
运行结果如下

waiting lock in f()
main has finished 

我感觉奇怪的是blockThread线程在执行时竟然一直阻塞在f()方法中,按理说BlockThread已经持有了BlockMutex的对象锁,不应该继续申请锁.经过一段时间思考后我明白了blockThread线程并没有持有BlockMutex的对象锁,blockThread初始化是在主线程中进行,而锁的申请是在构造器中完成,所以持有BlockMutex的对象锁是主线程,为了验证这一思想,我们只要让主线程执行f()方法,如果无等待执行成功则我们这一思想成立,更改main函数如下

public class LockInterruptTest {

    public static void main(String[] args) throws InterruptedException {
        BlockThread blockThread=new BlockThread();
        Thread thread = new Thread(blockThread);
        blockThread.getBlockMutex().f("main");
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        System.out.println("main has finished ");
    }

}

运行结果

main lock acquired in f() 
waiting lock in f()
main has finished 

猜想成立

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值