当前位置:网站首页>并发编程第8篇,AQS源码解读
并发编程第8篇,AQS源码解读
2022-08-08 23:36:00 【进击的豆子】
public class AqsLock {
public static void main(String[] args) {
Lock lock = new ReentrantLock(true);
Thread t1 = new Thread("t1"){
@Override
public void run() {
lock.lock();
System.out.println("t1=========start");
long l1= System.currentTimeMillis();
for (int i= 0;i<500000;i++){
System.out.println("t1线程执行的业务代码"+i);
}
long l2= System.currentTimeMillis();
System.out.println("t1业务执行时间=="+(l2-l1));
System.out.println("t1=========end");
lock.unlock();
}
};
Thread t2 = new Thread("t2"){
@Override
public void run() {
lock.lock();
System.out.println("t2=========start");
lock.unlock();
}
};
t1.start();
t2.start();
}
}
当T1线程第一次执行lock的时候,它会执行下面的方法
其中的sync是一个继承的AQS抽象类
用的是模板方法,模板方法设计模式,内部提供公共业务方法:nonfairTryAcquire(非公平锁重试),tryRelease(释放锁次数每次调用减一),isHeldExclusively(头部线程是等于当前线程),newCondition(创建condition对象),getOwner(获取现在拥有锁的对象,如果state==0,则为空说明没有线程获取得锁重新竞争锁),getHoldCount(获得重入次数),isLocked(是否有线程获取锁),readObject。和抽象方法lock。
Sync有两个实现类一个公平锁,一个非公平锁,因为上面传的true所以构造函数走的是公平锁的的lock方法
最后还是调用到公平锁的 tryAcquire传过来的acquires=1,state没人修改过值默认为0,或者调用了tryRelease减为了0
hasQueuedPredecessors判断是否有头结点,下面这段代码有很多种情况,写的真的很牛逼
其中有情况:第一次,node结点还是没有初始化
情况2:AQS队列有数据,但是突然插入的线程还没存入队列和下一个节点一起竞争锁
这里因为是第一次进来线程队列没有初始化所以hasQueuedPredecessors返回false,然后取反执行compareAndSetState执行cas把state置为1并且当前线程为ownerThread返回true,下面的else if 是线程的重入性,
tryAcquire返回的是true取反为false就不用走下面把当前线程添加到同步队列的方法也再往上也意味着lock方法结束
因为t1和t2线程是差不多同时启动的,因为t1.start在t2.start前面一点点所以可能主线程在顺序执行的时候t2可能会比t1晚那么一点点,当t2调用到lock的时候
再走到tryAcquire的时候c=1,当前getExclusiveOwnerThread为t1线程,因为t1还在执行for循环里面的业务代码还没有释放锁
所以t2线程一定会执行这个方法
Node.EXCLUSIVE第一次初始为null
最后在这一步阻塞了线程
边栏推荐
猜你喜欢
(Codeforce 757)E. Bash Plays with Functions(积性函数)
域前置通信过程和溯源思路
(2022牛客多校五)C-Bit Transmission(思维)
Introduction to Qt (5) - file operation, hotkey and mouse reading (implementation of txt window)
RecyclerView的多选模式
07 Spark on RDD 血缘关系
线性筛求积性函数
(2022杭电多校六)1010-Planar graph(最小生成树)
Excel 2013 下拉为“快速分拆”调整为“填充序号”
A preliminary study on the use of ndk and JNI
随机推荐
Hi3516 使用 wifi模块
时间对象的格式化
风控建模一:好坏标签定义
C语言中指针的介绍
51nod1656 合并trie树
(2022牛客多校五)H-Cutting Papers(签到)
(2022牛客多校五)D-Birds in the tree(树形DP)
Hand-written prometheus exporter-01-Gauge (dashboard)
ABP中的数据过滤器
获取当前时间的前/后某一天的日期
如何在Android中使用Realm数据库
ViewOverlay与ViewGroupOverlay
【深度学习】TensorFlow学习之路一:TensorFlow简介及线性回归、逻辑回归实现
读书笔记怎么写?
风控建模二:建模方案拟定
RecyclerView的多选模式
-Wl,--start-group ... -Wl,--end-group for resolving circular dependencies of several libraries
(2022牛客多校四)A-Task Computing (排序+动态规划)
51nod 2882最短路 (树链剖分)
[GYCTF2020]Ezsqli-1|SQL注入