摘要:解决这两种问题的方法是线程同步。在介绍线程同步之前,先来了解一下这两个问题。这篇文章介绍第二个问题内存一致性错误。
线程通信,主要通过共享访问进程资源。这种通信方式非常高效,但存在两个问题:线程冲突(thread interference) , 内存一致性错误(memory consistensy errors)。
解决这两种问题的方法是 线程同步(thread synchronization)。在介绍线程同步之前,先来了解一下这两个问题。
这篇文章介绍第二个问题:内存一致性错误。
内存一致性错误Memory consistency errors occur when different threads have inconsistent views of what should be the same data.
当不同的线程对于同一个数据有不一致的值时,产生内存一致性错误(Memory consistency errors)
产生 memory consistency error 的原因稍复杂,不过我们并不需要知道这其中的细节,只需要知道如何避免该错误。
要避免 memory consistency error,需要理解 happens-before 关系。这个关系是一个简单的保证,保证当内存被一个特定的操作修改时,对于另一个操作是可见的。
注:参考下边的例子,再回来理解上边的内容
一个例子令一个属性 couter 声明并初始化
int counter = 0;
这个 counter 被线程 A 和线程 B 共享
假定线程 A 对 couter 的操作为
couter++;
假定线程 B 对 couter 的操作为
System.out.println(couter);
如果上述两个操作在同一个线程,则可以肯定,最终输出的结果为1。但这两个操作分别在两个线程中执行,线程 B 最终输出的结果可能为0,因为无法保证线程 A 对 couter 的操作对于 B 是可见的 —— 即 B 无法判断 A 是否正在修改值
除非我们为 A 和 B 建立一个 happens-before 关系。
建立 happens-before 关系,方法就是 线程同步(Thread Synchronization)。这在另一个文章中详谈。
其实我们已经已经见过这种 happens-before 关系
当一个语句调用 Thread.start 创建新线程时,该语句之后的操作不仅和该语句有了 happens-before 关系,且和新线程中的 run 方法包含的所有操作都有了 happens-before 关系 —— 简单的说,就是主线程已知一个新线程要运行,对此主线程可以做一些处理,比如调用新线程的 Thread.join 方法等待其运行结束。
Thread.join 同理。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/65223.html
摘要:处理器通过缓存能够从数量级上降低内存延迟的成本这些缓存为了性能重新排列待定内存操作的顺序。从上述触发步骤中,可以看到第步发生了指令重排序,并导致第步读到错误的数据。内存屏障是用来防止出现指令重排序的利器之一。 这两天,我拜读了 Dennis Byrne 写的一片博文Memory Barriers and JVM Concurrency (中译文内存屏障与JVM并发)。 文中提到: ...
摘要:最近在学习各大互联网公司是如何处理数据一致性的。目前已知的有这么几种数据库做到情况下的强一致性淘宝淘宝顶级科学家阳振坤微博号阿里正祥,发出一则消息。然后因为数据库是的,内部把改动到了北美,君就可以看到消息了。 最近在学习各大互联网公司是如何处理数据一致性的。因为之前从事的不是这个方向的工作,所以并非什么经验之谈,只是一些学习笔记。所有资料来自互联网。 Consistent => Ev...
阅读 804·2021-09-22 16:01
阅读 2097·2021-08-20 09:37
阅读 1702·2019-08-30 15:54
阅读 1699·2019-08-30 15:44
阅读 845·2019-08-28 18:23
阅读 3024·2019-08-26 12:17
阅读 1026·2019-08-26 11:56
阅读 1547·2019-08-23 16:20