java之内存可见型
1、可见性的概念
一个线程对于共享变量的修改,能够及时被其他的线程看到。
2、什么是共享变量
一个变量在多个线程中的工作内存中都存在变量副本,那么这个变量在这几个线程之间共享。
3、Java线程的工作规则
(1)线程对于共享变量的所有操作都必须在自己的工作内存中,不能对主内存进行直接的操作
(2)不同线程之间无法直接通过访问其他线程工作内存的变量,线程间变量传递时通过主类存来完成的

4、synchronizied的原子性和可见性:
线程执行互斥代码的过程:
1、获得互斥锁
2、清空工作内存
3、中从主内存中拷贝变量的最新副本到工作内存
4、执行代码块
5、将更改以后的共享变量的值刷新到住内存
6、释放互斥锁
5、指令重排序:代码的书写顺序与实际执行的顺序不同,指令重排序是编译器或者处理器为了提高程序性能而做的优化
重排序不会给单线程带来内存可见性问题,但是在多线程的条件下,内存可见性就会出现问题
1、编译器优化的重排序(编译器优化)
2、指令级并行的重排序(处理器优化)
3、内存系统的重排序(处理器优化)
6、as-if-serial:无论如何进行重排序,执行结果应该和顺序执行的结果一致
7、volatile实现可见性:通过加入内存屏障和禁止重排序优化实现
1、对volatile变量执行写操作时,在写操作后面添加一条store屏障指令(将缓冲区值强制刷新到主内存)
2、对volatile变量执行读操作时,在读操作后面添加一条load屏障指令(让缓冲区值失效,要从主内存中重新读值)
3、通俗的来讲:volatile变量每次被线程访问时,都强迫从主内存中读取该变量的值,当变量值发生变化时,有强迫刷新到主内存,
这样在任意时刻,不同线程总能够看到该变量的最新值,以此实现内存可见性
4、线程写volatile变量
1、改变线程工作内存中volatile变量副本的值
2、将改变副本的值从工作内存刷新到主内存
5、线程读volatile变量
1、从主内存中读取volatile变量的最新值到线程的工作内存中
2、从线程的工作内存中读取volatile变量的副本
6、为什么volatile变量不能保证原子性:
volatile int num=0;
num++;
对于num++的操作要经历以下步骤
1、读取num的值
2、num+1;
3、写入num的值
这三步操作不能保证原子性
7、volatile变量的使用场景
1、对变量的写入操作不能依赖当前的值(不能与之前的值有关系)比如boolean,天气的变化
2、该变量没有包含在具体的其他变量中
java之内存可见型的更多相关文章
- Java虚拟机内存模型和volatile型变量
Java虚拟机内存模型 了解Java虚拟机的内存模型,有助于我们明白为什么会发生线程安全问题. 上面这幅图是<深入理解Java虚拟机-JVM高级特性与最佳实践>的书中截图. 线程共享的变量 ...
- java 工作内存
所谓线程的“工作内存”到底是个什么东西?有的人认为是线程的栈,其实这种理解是不正确的.看看JLS(java语言规范)对线程工作 内存的描述,线程的working memory只是cpu的寄存器和高速缓 ...
- Java设计模式之职责型模式总结
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6548127.html 所谓职责型模式,就是采用各种模式来分配各个类的职责. 职责型模式包括 ...
- Ehcache计算Java对象内存大小
在EHCache中,可以设置maxBytesLocalHeap.maxBytesLocalOffHeap.maxBytesLocalDisk值,以控制Cache占用的内存.磁盘的大小(注:这里Off ...
- [ 转载 ] Java Jvm内存介绍
一.基础理论知识 1.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序.程序开始执行时他才运行,程序结束时他就停止.你在同一台机器上 ...
- 关于Java虚拟机内存原型的基本知识
Java虚拟机内存原型的六个部分: 1.寄存器:我们在程序中无法控制 2.栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 3.堆:存放用new产生的数据 4.静态域:存放在 ...
- Java 堆内存和栈内存
看了一些别人总结的博客,感觉对堆内存和栈内存有了一个初步的认识.所以来写写自己对堆内存和栈内存的理解. Java把内存分成两种,一种叫做栈内存,一种叫做堆内存. 在函数中定义的一些基本类型的变量和对象 ...
- Java的内存分配机制
Java程序运行在JVM(Java Virtual Machine,Java虚拟机)上,可以把JVM理解成Java程序和操作系统之间的桥梁,JVM实现了Java的平台无关性,由此可 见JVM的重要性 ...
- 深入剖析Java虚拟机内存结构
深入剖析Java虚拟机内存模型 JVM整体架构 JVM整体架构如下: 通过编写代码来分析整个内存区域 public class Math { public static final Integer C ...
随机推荐
- VC++中的类的内存分布(上)(通过强制转换,观察地址,以及地址里的值来判断)
0.序 目前正在学习C++中,对于C++的类及其类的实现原理也挺感兴趣.于是打算通过观察类在内存中的分布更好地理解类的实现.因为其实类的分布是由编译器决定的,而本次试验使用的编译器为VS2015 RC ...
- 整数数组的定义,然后输入一个整数X,假定X不在这个数组,返回小于X位置的最大数目i而超过X位置的最小数目j
//整数数组的定义,然后输入一个整数x,假定X不在这个数组,返回小于X位置的最大数目i而超过X位置的最小数目j: //如果X在该阵列,返回位置的阵列中的数. 资源: #include<iostr ...
- css3选择器的比较(二) -- 包含字符串
二. 包含“字符串” 两种用法的区别是: a. “~=”,需要用空格分割, b. "*=",不需要任何分隔符 1. 资料 a) b) 2. html代码 <div tit ...
- ios开发学习笔记(1)
objective-c基础总结 第一二章 1.application:didiFinishLauchingWithOptions:程序启动后立即执行 2.启动界面代码格式:self.window = ...
- Matlab中的取整-floor,ceil,fix,round
FLOOR Round towards minus infinity. FLOOR(X) rounds the elements of X to the nearest integers toward ...
- 关于MATLAB中any和all的个人理解
any: any=1,有一个元素是1,即可: any=0,全部元素为0,即可. all: all=1,全部元素是1,即可: all=0,有一个元素是0,即可. ALL True if all elem ...
- ajax的get与post提交方式
Get方式的用户名验证 1.编写html代码 <form> 用户名[GET]:<input id="usernameID" type="text&quo ...
- java内存映射文件
内存映射文件能够让我们创建和修改大文件(大到内存无法读入得文件),对于内存映射文件,我们可以认为是文件已经全部被读入到内存当中,然后当成一个大的数字来访问,简化修改文件的代码. 1.directBuf ...
- SqlHelp
using System.Configuration;using System.Data; public class SqlHelp { private static string connectio ...
- 获取执行计划——EXPLAN PLAN
一般获取执行计划有四种途径:1.执行explain plan,查询结果输出表.2.查询动态性能视图,它显示缓存在库缓存中的执行计划(有时查不出结果是因为执行计划已经不在库缓存中).3.查询AWR或St ...