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;
}
}
}
}
只是简单的生成一个 node 作为 head ,将参数 node 变为 tail , 最后将 tail 的 prev 指向 head ,head 的 next 指向 tail 。
大牛炫技
1
lux182 OP 后续时候,把参数 node 作为 tail 。tail 的 prev 指向前 tail 。前 tail 的 next 指向参数 node 。
以此形成 node 链表。 简单的几行代码就实现了,真是鬼斧神工 |
2
Canon1014 2021-12-13 17:53:43 +08:00
好像是为了解决并发性能初始化的时候首节点做了个空的虚节点,第二轮才真正的设置尾结点
说错了楼下请打醒我,面试说错就社死了 |
3
Canon1014 2021-12-13 17:54:23 +08:00
好像是为了解决并发问题,初始化的时候首节点做了个空的虚节点,第二轮才真正的设置尾结点
说错了楼下请打醒我,面试说错就社死了 性能->问题 |
4
liian2019 2021-12-13 17:54:43 +08:00
看一次忘一次
|
5
fkdog 2021-12-13 19:53:53 +08:00 1
其实 AQS 的本质其实就是双向链表+LockSupport.park()和 LockSupport.unpark()实现的同步器。单看 enq 并没有什么卵用,你还得结合 shouldParkAfterFailedAcquire 、unparkSuccessor 、setHeadAndPropagate 、cancelAcquire 几个方法一起看。
任意时候 node 状态都会发生变化,所以针对链表的操作用了大量的 forloop+cas 操作来保证并发安全。jdk8 版本的这个 AQS 应该是经过了 N 个版本的修订才会搞得这么零零散散一堆方法。。 我记得 8 版本以后的某个版本好像 aqs 有大篇幅的重写。。 |