关于多线程编程的问题

2023-02-03 15:12:40 +08:00
 oldshensheep

多线程编程有许多问题……这是一些复现这些问题的例子。
具体为什么会出现这些问题就不多说了……

指令重排( Instruction reordering)

多线程访问共享变量的顺序可能不是你代码写的顺序。

例子 https://stackoverflow.com/questions/52648800/how-to-demonstrate-java-instruction-reordering-problems

可见性问题(Visibility)

多线程修改一个变量,另一个线程读取的可能是修改前的值

学 Java 的应该都知道的一个例子,单例模式中的双重检查锁(Double checked locking)。
还有一个例子,在上面 stackoverflow 网站中给出的例子当中代码执行出乎意料,其实也有可能是内存可见性的问题。
在评论中也有人指出了这个问题。不过在 X86 中不存在可见性问题。

虚假唤醒(Spurious wakeup)

线程会莫名其妙的被唤醒

例子 https://www.v2ex.com/t/902578 见回复简化的例子 https://www.v2ex.com/t/902578#r_12468983

伪共享(False sharing)

多线程访问同一个缓存行,导致缓存频繁失效。

例子 https://jenkov.com/tutorials/java-concurrency/false-sharing.html
去掉 @jdk.internal.vm.annotation.Contended 和不去掉的运行时间差别非常大。40s -> 6s

原子性

多线程读取修改同一个变量,修改会被相互覆盖。

Int a = 0

Thread 1 : 
for 0 to 100:
    a=a+1

Thread 2 : 
for 0 to 100:
    a=a+1

最后的结果不一定是 200

1787 次点击
所在节点    程序员
4 条回复
amlee
2023-02-03 15:26:20 +08:00
你不都自问自答了吗?哪还有问题
oldshensheep
2023-02-03 15:29:31 +08:00
@amlee 啊?我就是分享一下
lzj724
2023-02-03 15:40:48 +08:00
还有 MESI 协议
z4oSkDNGGC2svsix
2023-02-03 16:14:16 +08:00
帖子应该构成一个讨论, 否则你可以发到自言自语板块, 又或者你可以发到分享板块

而且你发的这些应该不是多线程而是并发问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/912912

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX