V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  amiwrong123  ›  全部回复第 27 页 / 共 40 页
回复总数  781
1 ... 23  24  25  26  27  28  29  30  31  32 ... 40  
2020-06-10 08:20:45 +08:00
回复了 amiwrong123 创建的主题 Java 为啥 AQS 的 CondtionObject 的 firstWaiter 不需要是 volatile 的?
@vk42
好吧,所以相当于决定权给了用户,作者默认使用者是按照正确用法使用的
2020-06-10 08:16:43 +08:00
回复了 amiwrong123 创建的主题 Java 为啥 AQS 的 CondtionObject 的 firstWaiter 不需要是 volatile 的?
@muyunn
是的,标准用法是这样
2020-06-10 00:30:23 +08:00
回复了 amiwrong123 创建的主题 Java 为啥 AQS 的 CondtionObject 的 firstWaiter 不需要是 volatile 的?
@sagaxu
额,我好像没懂你意思。所以你想说 firstWaiter 不加 volatile,就会有问题呗
@Aresxue
condition 这两天我就会去看,不过估计也不可能是它。哎,aqs 里面好多细节,就是不知道为什么这么写
@U2Fsd
@triple7
@pangru
@WeKeey
@aapon
问一下各位,是不是必须得去 小区所属地区的派出所 换领身份证,还是说随便找一个派出所就可以啦
@U2Fsd
好吧,我刚打电话问了 我住的附近的居委会,发现 房东已经帮我 登记过了 实有人口登记了,身份证都给我报出来了。说去派出所 都能 查到我的实有人口登记信息。

等会我再打电话问问派出所,是不是可以直接去派出所了。
@brust
是的,一般就为 SIGNAL 。
@Aresxue
你的意思是 h.waitStatus != 0 是为了对应头结点为 CANCELLED 的情况吗,纳尼,这不可能吧。

要知道头结点的线程其实就是 已经获得了独占锁的线程,也就是 AQS 的 exclusiveOwnerThread 成员。而取消这个动作,只是针对于 在等待队列中的节点才会执行的动作,我头结点都已经获得了独占锁,是不可能执行取消动作的。
@MisakaTang
StackOverflow 也提问过,好多时候是根本没人回答。还是 v 站好,个个是人才,说话又好听
@guyeu
是,我那个地方看错了,还是基础不扎实。

没想到还有论文,惊到了,回头看看
2020-05-23 10:45:41 +08:00
回复了 amiwrong123 创建的主题 Java AQS 里的 setHeadAndPropagate 以及关于 PROPAGATE 信号的疑问?
@guyeu
@luckyrayyy
谢谢回复,之前这块确实想错了,看来以后发帖前还是得看仔细,我承认错误。

不过看完还是有疑问。分析如下


- 入参`node`所代表的线程(这个 node 的 Thread 成员)一定是当前执行的线程,
- 看第一个 if 的判断:
- 如果`propagate > 0`成立的话,说明还有剩余共享锁可以获取,那么短路后面条件。
- 如果`propagate = 0`成立的话,说明没有剩余共享锁可以获取了,按理说不需要唤醒后继的。也就是说,很多情况下,调用 doReleaseShared,会造成 acquire thread 不必要的唤醒。
- 继续看,如果`propagate > 0`不成立,而`h.waitStatus < 0`成立。这说明旧 head 的 status<0 。但如果你看 doReleaseShared 的逻辑,会发现在 unparkSuccessor 之前就会 CAS 设置 head 的 status 为 0 的,在 unparkSuccessor 也会进行一次 CAS 尝试,因为 head 的 status 为 0 代表一种中间状态( head 的后继代表的线程已经唤醒,但它还没有做完工作),或者代表 head 是 tail 。而这里旧 head 的 status<0,只能是由于 doReleaseShared 里的`compareAndSetWaitStatus(h, 0, Node.PROPAGATE)`的操作,而且由于当前执行 setHeadAndPropagate 的线程只会在最后一句才执行 doReleaseShared,所以出现这种情况,一定是因为有另一个线程在调用 doReleaseShared 才能造成,而这很可能是因为在中间状态时,又有人释放了共享锁。
- 继续看,如果`propagate > 0`不成立,且`h.waitStatus < 0`不成立,而第二个`h.waitStatus < 0`成立。注意,第二个`h.waitStatus < 0`里的 h 是新 head (很可能就是入参 node )。第一个`h.waitStatus < 0`不成立很正常,因为它一般为 0 。第二个`h.waitStatus < 0`成立也很正常,因为只要新 head 不是队尾,那么新 head 的 status 肯定是 SIGNAL 。所以这种情况只会造成不必要的唤醒。


简单的说,我认为,检查第一个`h.waitStatus < 0`,是因为被唤醒的线程处于中间状态,而 doReleaseShared 在这个中间状态,只会设置`compareAndSetWaitStatus(h, 0, Node.PROPAGATE)`,不会调用 unparkSuccessor(h);,因为线程已经被唤醒了。

但检查第二个`h.waitStatus < 0`就有点想不通,感觉他只会造成不必要的唤醒?好奇怪
@wutiantong
我承认我菜,那层主能讲解下这个常识吗
@luckyrayyy
哈哈哈,可以,直接问本人
@vitoliu
卧槽,无情~
2020-05-21 18:36:06 +08:00
回复了 amiwrong123 创建的主题 Java AQS 里的 setHeadAndPropagate 以及关于 PROPAGATE 信号的疑问?
我好后悔,我是不是应该弄个吸引人的标题的…
@hfc
是嘛,在 interrupt 的源码里能看到有调用 unpark 的吗
2020-05-17 20:18:30 +08:00
回复了 amiwrong123 创建的主题 Java AQS 里 hasQueuedPredecessors 里为啥要先读取 tail 成员啊?
@liangdu
>只是你对“语序逻辑是否依赖”没理解对而已,其实是有依赖的

我怎么看怎么赶脚 Node t = tail; Node h = head;这两句没啥依赖关系啊。

对了,我又突然想起来了,难道是这是两次 volatile 写操作,然后会在每次 volatile 写后面,加 StoreStore 和 StoreLoad 屏障,然后才能 这两句 不会被 指令重排序 ?是因为这个原因吗
1 ... 23  24  25  26  27  28  29  30  31  32 ... 40  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3466 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 103ms · UTC 11:50 · PVG 19:50 · LAX 03:50 · JFK 06:50
Developed with CodeLauncher
♥ Do have faith in what you're doing.