网站首页 > 技术文章 正文
前言
像我大佬烟说过:面试的时候颜值可以提高分数,没有颜值的话就需要会点J.U.C。人丑就要多读书,没错说的就是我。 AQS是AbstractQueuedSynchronizer缩写,作者是
@author Doug Lea
并发大神,致敬一哈。J.U.C很多东西都是基于AQS进行实现的,所以有必要去研究它。
AQS
重要变量
state加锁的个数 Node 类似链表的实现,可以储存Thread的顺序 cas的引用
private static final Unsafe unsafe = Unsafe.getUnsafe(); Java无法直接访问底层操作系统,而是通过本地(native)方法来访问。不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作
乐观锁也是cas思想的一种实现,这里是使用cpu 底层来实现cas。 cas引入目的 在无锁的情况下,线程安全地执行赋值操作 像state(持有锁的个数)这个需要控制原子性的,其次是可见性:volatile
/**
* The synchronization state.
*/
private volatile int state;
unsafe
上面已经解释了这个类,可以调用硬件级别的原子操作。
unsafe.compareAndSwapInt(this, stateOffset, expect, update);
cas就不扯了,西西~
AtomicInteger
/**
* Atomically adds the given value to the current value.
*
* @param delta the value to add
* @return the updated value
*/
public final int addAndGet(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
}
可以看到也是使用cas去进行原子性增长
ReentrantLock
可重入锁,就是你原本租的单车,还没还,再次去租这一辆,还是你的。只是会标记你借了两次。
lock方法
ReentrantLock有公平锁,非公平锁 都会调用acquire方法
tryAcquire是一个重要方法,后面解读
加锁原理
判断AQS的state,如果为0,加锁并记录当前线程。如果state不为0,判断当前线程是否是当前lock保存的线程,是的话state+1。否的话会调用addWaiter,将线程放到AQS Node 插入到队列里面等待。
/**
* Inserts node into queue, initializing if necessary. See picture above.
* @param node the node to insert
* @return node's predecessor
*/
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
公平锁
每个线程都有鸡费拿到锁
非公平锁
ReentrantLock默认是非公平锁。 看运气拿到锁。
公平锁跟非公平锁的代码区别
FairSync hasQueuedPredecessors
公平锁会从AQS Node队列里面拿,采用FIFO先进先出的算法,大家都有鸡费拿到锁。
非公平锁是没有从AQS去拿排队的线程,大家随缘抢锁。
共享锁系列
何为共享锁?大家都可以去获取,而不是只能一个线程去获取。就像饭堂一样,大噶都可以去打饭,独占锁:大家排成一队,老子占了位置,没有点完餐,其他人点不了。
Semaphore
信号量控制,限流专用,西西~
ReentrantLock是独占锁,Semaphore是共享锁
源码
包含公平锁和非公平锁,之前提及过,这里就不再解释~主要是讲下共享锁和独占锁的区别! 共享锁和独占锁的区别
独占锁
解读:只能当前线程去获取,如果是公平锁,而且当前锁不属于它的,排队去。非公平锁,则你抢到算你的。
共享锁
解读:大家随便抢,饭堂记录你们领了几份盒饭,盒饭不够的时候你们等等,等到有盒饭再分发。
方法名也有所不同:nonfairTryAcquire & nonfairTryAcquireShared ,有点东西~
至于semaphore控制并发的其他原理需要看下它的acquire方法
/**
* Acquires in shared interruptible mode.
* @param arg the acquire argument
*/
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
CountDownLatch
这个大家也不陌生吧,就是一个起泡枪,啪......大家线程一起跑
await源码
countDown源码
public void countDown() {
sync.releaseShared(1);
}
CyclicBarrier
概念:大家自由活动,集合声一响大家就过来集合(线程各自跑,跑完一起结束)
源码
本身来看跟AQS没有太大关系,跟ReentrantLock以及Condition有关系,await来阻塞。用屁股也能想出来,大家线程随便跑,跑完阻塞你,等大家跑完再释放。
猜你喜欢
- 2024-10-20 操作系统概论:第四章 内存管理 操作系统内存管理笔记
- 2024-10-20 推荐一款nginx+redis+ehcache高并发与高可用缓存架构
- 2024-10-20 真正的缓存之王,Google Guava 只是弟弟
- 2024-10-20 操作系统-存储管理与文件管理-笔记
- 2024-10-20 图解Linux进程优先级 linux 进程优先级 线程优先级
- 2024-10-20 高性能缓存 Caffeine(一) 高效缓存cache的作用
- 2024-10-20 一文读懂进程调度算法 进程调度常用算法及其思想
- 2024-10-20 缓存最关心指标有哪些,这篇文章告诉你?
- 2024-10-20 缓存算法:LRU、LFU、随机替换等常见算法简介
- 2024-10-20 Caffine Cache 在 SpringBoot 中的使用
你 发表评论:
欢迎- 最近发表
-
- 在 Spring Boot 项目中使用 activiti
- 开箱即用-activiti流程引擎(active 流程引擎)
- 在springBoot项目中整合使用activiti
- activiti中的网关是干什么的?(activiti包含网关)
- SpringBoot集成工作流Activiti(完整源码和配套文档)
- Activiti工作流介绍及使用(activiti工作流会签)
- SpringBoot集成工作流Activiti(实际项目演示)
- activiti工作流引擎(activiti工作流引擎怎么用)
- 工作流Activiti初体验及在数据库中生成的表
- Activiti工作流浅析(activiti6.0工作流引擎深度解析)
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)