关于JAVA的Reentrantlock 的lock()方法,在多线程的场景下为什么就不会同时lock成功?

颖辉小居 发布于 2021/04/26 20:53
阅读 280
收藏 0

开源之夏第三届火热来袭,高校学生参与赢万元奖金!>>>

看了代码不知道我分析的对不对,lock()是调用了 NonfairSync 下图的lock方法

其中compareAndSetState是基于 unsafe.compareAndSwapInt(this, stateOffset, expect, update); 实现的,这个方法是原子性的,所以不会有线程安全问题。 当它返回true 的时候表示从无锁到加互斥锁成功。 如果返回false 则表示两种场景:1、当前线程重复lock,重入锁。2、另外一个线程加锁时发现已经被抢,获取锁失败。 上面两种场景都会进入 acquire(1);

如下图:

acquire(1); 里面就看的比较难懂了。

tryAcquire(arg)尝试加锁,如果锁没有被占用,则当前线程利用cas加锁,成功返回true方法结束,失败则返回false(原子性)。再看是重入锁则state自增1。以上都不是则返回false。

回false 则将当前线程封装为Node添加到AQS队列中。

综上所诉,acquire(1); 大体意思明白了,但是不明白acquire(1); 怎么保证线程安全的。

比如第一个线程A没有释放lock 的时候,第二第三个线程B,C执行lock()。 执行到compareAndSetState的时候B,C都得到false。都会进入acquire(1);。这时候怎么保证线程安全的。

 

加载中
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部