AQS ReentrantLock学习记录

AQS是基于FIFO等待队列的同步器,其state变量用于表示锁的状态。公平锁遵循先来先得原则,而非公平锁则不保证。ReentrantLock的acquire方法包含尝试加锁、加入队列及等待抢锁等步骤。tryAcquire方法根据state判断是否能获取锁,addWaiter方法处理新线程入队,而acquireQueued方法处理线程在队列中的竞争和等待策略。
摘要由CSDN通过智能技术生成

AQS:   AQS是基于先进先出(FIFO)的等待队列来实现锁的同步器, AQS定义了一个state变量, 必须原子性的修改这个变量

ReentrantLock公平锁和非公平锁

公平锁: 线程获取锁的顺序是按照线程访问锁的先后顺序获取的,最前面的线程总是最先获取到锁

非公平锁: 线程获取锁的顺序是随机的,并不会遵循先来先得的规则,所有线程会竞争获取锁

不公平的地方体现

 这个lock的时候, 非公平锁使用compareAndSetState(0,1)方法来判断是否能修改seate的值, 能修 改就会占用锁, 其他没获取到锁的线程就会进入队列等待

公平锁则没有实现, 那个线程先来访问即可先获取到锁

state变量在ReentrantLock中的含义

1. state == 0 :  表示当前没有线程持有锁

2. state != 0 :  表示有线程持有锁了

    state从 0 -> 1 就是线程持有锁的过程

     当已经持有锁的线程重新获取锁时, state的值就会 + 1 (重入)

acquire(1)方法: 

1. 尝试加锁 

2. 如果抢占锁失败, 把自己加入到队列中

3. 在队列中等待, 伺机抢锁

tryAcquire(arg)方法:

1. 获取state的值

2. 判断state的值 :

当state == 0 , 当前没有人持有锁, 判断队列中有没有排队的线程, 没人即可尝试抢占锁, 抢占到了设置标记

setExclusiveOwnerThread(current);

当state != 0,  先判断当前线程是否和占有锁的线程是同一个, 如果是的话将 state + 1

addWaiter(Node mode)方法:

Node

head:  指向头节点的引用

tail:  指向尾节点的引用

当tail == null , 初始化队列会创建一个虚拟的头节点, 在下一次循环中把当前线程包装的Node对象的pred指向虚拟的头节点, 通过compareAndSetTail(t, node)方法抢占tail应用

当队列已经初始化过

将tail的引用指向, 当前线程node节点

当有新的线程来时: 

acquireQueued(final Node node, int arg)方法

当发现自己的上一个节点是头节点时 ---->  尝试抢占锁

抢占成功 setHead(Node) 把自己设置成头节点  p.next ==null

抢占失败 shouldParkAfterFailedAcquire(p, node) 方法中断

unparkSuccessor(node) 唤醒

未完 暂时只学到这里, 有理解不好的地方 大家多多指正

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值