
1 xlzy905 2020-12-29 11:32:37 +08:00 频繁了 |
2 lewis89 OP 先 mark 一下,昨天一下子吸收了 100 多人 |
3 xujihua 2020-12-29 12:36:10 +08:00 加不上了 拉一下可以嘛 微信 ID:bW9yYXRn |
4 sanwantian 2020-12-29 12:45:34 +08:00 拉一下可以嘛 微信 ID:finalesanwantian |
5 lewis89 OP 已拉 |
6 x940727 2020-12-29 13:59:25 +08:00 求拉 BASE64:WHU1NzIxMTcyMzU= | ||
7 banjueaz 2020-12-29 14:19:13 +08:00 微信 ID:zb547856757 麻烦拉一下 |
8 lewis89 OP 6-7 已拉 |
9 TheF00L 2020-12-29 14:49:50 +08:00 昨天加就频繁了 微信 ID: dsdnnt 麻烦拉一下 |
10 boblin 2020-12-29 15:52:43 +08:00 前端可以么 |
11 wdmm 2020-12-29 16:06:11 +08:00 求拉 Base64: endkMTE3ODQ2MTQ5MA== |
12 MrCard 2020-12-29 16:09:46 +08:00 求拉,微信号:TW96YXJrIA== |
14 wr516516 2020-12-29 16:12:46 +08:00 楼主还帮忙拉嘛 d3I1MTY1MTY= |
15 mosliu 2020-12-29 16:13:56 +08:00 VX 同 id 求拉 |
16 hun2008hun 2020-12-29 16:18:08 +08:00 这代码有 bug 呀,可见性的反义词是不一定可见,以前也看到人拿这代码来纠结 system.out ,完全不能理解在想什么 |
17 zhanbiqiyu 2020-12-29 16:20:50 +08:00 d3UzMDEzNTY4MQo= 大家可以加我微信,我拉大佬们进群 |
19 toma77 2020-12-29 16:24:47 +08:00 求啦 微信号:bHhzdW5iaW4= |
20 lewis89 OP @hun2008hun #16 你去反编译看看就知道了,我研究的本来就是为什么 DEMO1 会在那里死循环,从 GDB 反汇编来看 主线程就是读不到 num 的最新值,至于为什么这样 我也不清楚,但是后面的 lock 指令 确确实实有内存栅栏的作用 |
21 lewis89 OP @hun2008hun #16 纠结 System.out ? System.out 本身在 JIT 下也是有一个 lock 指令生成的,刚好就是这个 lock 之类充当了内存栅栏 |
22 lewis89 OP |
23 Cowhitewhite 2020-12-29 16:38:05 +08:00 求拉:Y293aGl0ZXdoaXRl |
24 cnzjl 2020-12-29 16:52:21 +08:00 求拉 R2xhZE1vbnN0ZXI= |
25 hun2008hun 2020-12-29 17:13:30 +08:00 @lewis89 因为 demo1 有 bug,而且严谨说不一定死循环,只是你的 cpu 是这样。 第二个问题:lock 的话要不把 sleep(1000)去掉再跑下? |
26 lewis89 OP @hun2008hun #25 我管它有没有 bug? 只要是代码 确实有人会这么想 也这么犯傻用过,我就去查问题出在哪里就好了,我 JDK8 在树莓派上就没这个事情,你去掉 sleep(1000)又要为什么,它这个本来就是要循环去读,主线程循环 10 秒钟后还是读不到最新的值,那又是为什么。 只有用 lock 才能读到,lock 本身就是有内存栅栏的特性,我早就知道这个特性,这个东西只是验证 告诉你怎么一回事。 |
27 lewis89 OP @hun2008hun #25 而且我在很多库的代码里面都看到有人用 volatile 去做可见性的同步,但同时并未使用 happen-before 语义 |
28 junziyangyang 2020-12-29 18:18:21 +08:00 via iPhone 求拉 feng-junzi |
29 HAluelue 2020-12-30 09:08:33 +08:00 求拉 andyis1iin |
30 GunsRose 2020-12-30 09:16:38 +08:00 求拉 songtao22 |
31 will2zuo 2020-12-30 10:12:34 +08:00 求拉 zz546398578 |
32 young1lin 2020-12-30 13:54:35 +08:00 使用 System.out 会导致锁粗化的。。。你可以看看极客时间的专栏《 Java 并发编程实战》有一章的评论里面就说过,我记得是日志打印的那一章。 |
36 ezksdo 2021-01-23 14:40:33 +08:00 原文里就有答案,能扯这么多。有 lock 就全局可见了?都锁的不是一个位置。 |
37 lewis89 OP @ezksdo #36 哈,你不想研究就算了,不要瞎批评,我还真就告诉你 X86 有 lock 就能保障可见性 好吗? 跟锁不锁一个位置没有任何关系 |
40 ezksdo 2021-01-23 15:55:07 +08:00 via iPhone 推荐你用 jitwatch 吧,看你 gdb 用得也费劲。这里就是 jit 优化,而打印函数有副作用,没有优化 |
41 ezksdo 2021-01-23 15:56:39 +08:00 via iPhone 你也不想想,不加 volatile 他就永远不写回内存吗? |
42 lewis89 OP @ezksdo #41 我不知道 JVM 为什么会有这种优化,jitwatch 又不能 debug,我在 gdb 里面 已经看过了,那个内存地址读出来的值就是 0 ,无论多久都是 0,至于是主线程 读到的是未失效的 L1/L2 cache,还是什么,我就不在乎了 |
43 lewis89 OP @ezksdo #41 https://www.zhihu.com/question/263528143/answer/270308453 而且你从这个原答案里面可以看到 lock addl $0x0, (%rsp); 对 rsp 指针 + 0 操作是毫无意义的,rsp 是栈顶指针 lock 是让 cache 失效,保证可见性,如果可见性没有保证,代码依旧会死循环 而对 变量 i 加 volatile 属性 并没有使用 happen before |
44 lewis89 OP @ezksdo #41 关键是我那个死循环的地方 你有留意看了没有,跟激进编译半毛钱关系都没有 第一步要通过 R15 寄存器 偏移 0x108 的位置去取值, 第二步才是跟存放了 立即值 0 的 RAX 寄存器比较 比较失败跳回第一步 ,这跟 JVM 激进优化有半毛钱关系? 分明就是 [R15 + 0x108] 寄存器的指针 取不到新的值 |
45 ezksdo 2021-01-23 16:28:03 +08:00 via iPhone cache 以行为单位,打印函数有 lock 并不能导致 num 变量可见,写 volatile 就是 happens before volatile 读的,我不知道你说的使用是什么 |
46 lewis89 OP @ezksdo #45 如果读写 volatie.. 都是在同一个线程里面, 又何来一个线程 对 另外一个线程 观测到的 happen before ? |
47 lewis89 OP @ezksdo #45 你要 A 线程 写了 volatile,另外一个 B 线程 后续去读 volatile,保障 B 线程能观测到 A 线程写 volatile 的事情都发生,这才算是 happen before |
48 lewis89 OP 你要 A 线程 写了 volatile,另外一个 B 线程 后续去读 volatile,保障 B 线程能观测到 A 线程写 volatile 之前的事情都发生,这才算是 happen before |
49 lewis89 OP @ezksdo #45 你要 A 线程 写了 volatile,另外一个 B 线程 后续去读 volatile,保障 B 线程能观测到 A 线程写 volatile 之前的事情都发生,这才算是 happen before |