千家信息网

Java内存模型的知识点讲解

发表于:2024-10-03 作者:千家信息网编辑
千家信息网最后更新 2024年10月03日,本篇内容介绍了"Java内存模型的知识点讲解"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!内存模型
千家信息网最后更新 2024年10月03日Java内存模型的知识点讲解

本篇内容介绍了"Java内存模型的知识点讲解"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

内存模型 (memory model)

内存模型描述的是程序中各变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节.

不同平台间的处理器架构将直接影响内存模型的结构.

在C或C++中, 可以利用不同操作平台下的内存模型来编写并发程序. 但是, 这带给开发人员的是, 更高的学习成本.相比之下, Java利用了自身虚拟机的优势, 使内存模型不束缚于具体的处理器架构, 通过Java内存模型真正实现了跨平台.(针对hotspot jvm, jrockit等不同的jvm, 内存模型也会不相同)

内存模型的特征:

a, Visibility 可视性 (多核,多线程间数据的共享)

b, Ordering 有序性 (对内存进行的操作应该是有序的)


Java内存模型 ( java memory model )

根据Java Language Specification中的说明, jvm系统中存在一个主内存(Main Memory或Java Heap Memory),Java中所有变量都储存在主存中,对于所有线程都是共享的。

每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。

其中, 工作内存里的变量, 在多核处理器下, 将大部分储存于处理器高速缓存中, 高速缓存在不经过内存时, 也是不可见的.

jmm怎么体现可视性(Visibility) ?

在jmm中, 通过并发线程修改变量值, 必须将线程变量同步回主存后, 其他线程才能访问到.

jmm怎么体现有序性(Ordering) ?

通过Java提供的同步机制或volatile关键字, 来保证内存的访问顺序.

缓存一致性(cache coherency

什么是缓存一致性?

它是一种管理多处理器系统的高速缓存区结构,其可以保证数据在高速缓存区到内存的传输中不会丢失或重复。(来自wikipedia)

举例理解:

假如有一个处理器有一个更新了的变量值位于其缓存中,但还没有被写入主内存,这样别的处理器就可能会看不到这个更新的值.

解决缓存一致性的方法?

a, 顺序一致性模型:

要求某处理器对所改变的变量值立即进行传播, 并确保该值被所有处理器接受后, 才能继续执行其他指令.

b, 释放一致性模型: (类似jmm cache coherency)

允许处理器将改变的变量值延迟到释放锁时才进行传播.

Java内存模型的缓存一致性模型 - "happens-before ordering(先行发生排序)"

一般情况下的示例程序:

x = 0;  y = 0;  i = 0;  j = 0;   // thread A  y = 1;  x = 1;   // thread B  i = x;  j = y;

在如上程序中, 如果线程A,B在无保障情况下运行, 那么i,j各会是什么值呢?

答案是, 不确定. (00,01,10,11都有可能出现),这里没有使用Java同步机制, 所以Java内存模型有序性和可视性都无法得到保障. happens-before ordering( 先行发生排序) 如何避免这种情况? 排序原则已经做到:

a, 在程序顺序中, 线程中的每一个操作, 发生在当前操作后面将要出现的每一个操作之前.

b, 对象监视器的解锁发生在等待获取对象锁的线程之前.

c, 对volitile关键字修饰的变量写入操作, 发生在对该变量的读取之前.

d, 对一个线程的 Thread.start() 调用 发生在启动的线程中的所有操作之前.

e, 线程中的所有操作 发生在从这个线程的 Thread.join()成功返回的所有其他线程之前.

为了实现 happends-before ordering原则, Java及JDK提供的工具:

a, synchronized关键字

b, volatile关键字

c, final变量

d, java.util.concurrent.locks包(since jdk 1.5)

e, java.util.concurrent.atmoic包(since jdk 1.5)

使用了happens-before ordering的例子:

1) 获取对象监视器的锁(lock)

(2) 清空工作内存数据, 从主存复制变量到当前工作内存, 即同步数据 (read and load)

(3) 执行代码,改变共享变量值 (use and assign)

(4) 将工作内存数据刷回主存 (store and write)

(5) 释放对象监视器的锁 (unlock)

注意: 其中4,5两步是同时进行的.

这边最核心的就是第二步, 他同步了主内存,即前一个线程对变量改动的结果,可以被当前线程获知!(利用了happens-before ordering原则)

对比之前的例子

如果多个线程同时执行一段未经锁保护的代码段,很有可能某条线程已经改动了变量的值,但是其他线程却无法看到这个改动,依然在旧的变量值上进行运算,最终导致不可预料的运算结果。

"Java内存模型的知识点讲解"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

内存 线程 模型 变量 处理器 处理 缓存 工作 一致 一致性 主存 量值 数据 程序 同步 知识 有序 关键 关键字 对象 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 夕锦网络技术工作室 数据库文件有东西导出是空的 网络安全知识竞赛中职 水电费管理系统连接数据库 广州市维客网络技术有限公司 智慧安全的服务器 长沙java软件开发流程 阿里服务器最低价格 kinect骨骼数据库 重庆四维网络技术 2018江苏网络安全宣传 网络安全的属性不包括什么 熬夜看书软件开发 代理屏幕共享软件开发 数据库float占几个字节 网络安全法谣言 t 服务器到期还可以用的吗 天融信网络安全产品怎么样 剑网三的服务器是国产的吗 远程登录服务器桌面提示安全登录 演播室多通道视频服务器是干啥呢 河南吉夫森软件开发有限公司 龙芯中科服务器管理员 天津服务器托管社区云服务器 内蒙古新一代软件开发价格 计算机网络技术专业对口 网络安全哪家强就数天融信 ibm 7947服务器启动不了 数据库float占几个字节 东莞自助餐桌上点餐软件开发
0