java 对象内存模型 博客分类: java面试 java对象内存模型
基础
在Java中,所有实例域(成员变量/成员方法)、静态域和数组元素存储在堆内存中,堆内存在线程之间共享,会存在内存可见性问题,受内存模型影响
Java内存模型的主要目标是定义程序中堆内存变量的访问规则,线程之间的通信和同步由Java内存模型控制
主内存与工作内存
java内存模型规定了所有的实例域(成员变量/成员方法)、静态域和数组元素都存储在主内存中, 除此之外每个线程都有自己的工作内存, 线程的工作内存中保存了被该线程使用到的变量的副本拷贝, 线程对变量的所有操作(读取, 赋值等)都必须在工作内存中进行, 而不能直接读写主内存中的变量. 不同的线程之间也无法直接访问对方工作内存中的变量, 线程间变量值的传递均需要通过主内存来完成
重排序
为了提高程序执行的性能,编译器和处理器通常会对指令做重排序
1属于编译器重排序,2和3属于处理器重排序
这些重排序都可能导致多线程程序出现内存可见性问题,为了避免这些问题,JMM的重排序规则会禁止特定类型的重排序
JMM的编译器重排序规则会禁止特定类型的编译器重排序;JMM的处理器重排序规则会要求Java编译器在生成指令序列时,通过插入特定类型的内存屏障指令来禁止特定类型的处理器重排序
JMM属于语言级的内存模型,它确保在不同的编译器和处理器平台上,通过禁止特定类型的编译器和处理器重排序,为程序员提供一致的内存可见性保证
Volatile与Synchronized
对于volatile修饰的变量,当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的
volatile变量对所有线程是立即可见的,对volatile变量的所有写操作都能立刻反应到其他线程之中
JVM规范规定了任何一个线程修改了volatile变量的值都需要立即将新值更新到主内存中, 任何线程任何时候使用到volatile变量时都需要重新获取主内存的变量值
两者区别
1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
3.volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
4.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
5.volatile标记的变量不会被编译器优化(禁止指令重排序优化,即执行顺序与程序顺序一致);synchronized标记的变量可以被编译器优化
上一篇: 什么是Ruby On Rails(转贴) RailsRuby网络应用配置管理框架
下一篇: Response.ContentType 详解 博客分类: java基础 xslxmlhtmlxhtmlexcel
推荐阅读
-
java 对象内存模型 博客分类: java面试 java对象内存模型
-
day_07_Java类与对象 博客分类: Java_zhuhw Java类Java对象
-
关于使用Hibernate向数据库中存取java对象 博客分类: BLOB,oracle Blobhibernatejava对象oracle
-
java 内存 作用域 clone 对象 java内存作用域clonejava对象
-
JavaWEB前端向服务器端发送对象 博客分类: java JavaJavaWEB
-
深入java虚拟机之内存模型 博客分类: java基础 Java虚拟机内存模型
-
JVM监控与故障处理 博客分类: java编程 java虚拟机Java堆栈监控Java内存调优java服务监控
-
java对象的访问方式 博客分类: java虚拟机 java虚拟机
-
Effective Java读书笔记、感悟——2.1对所有对象都通用的方法之equals 博客分类: Java_SE effectivejava对象通用方法equals
-
《effective java》之一:创建和销毁对象 博客分类: Java effectivejava