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之内存可见型的更多相关文章

  1. Java虚拟机内存模型和volatile型变量

    Java虚拟机内存模型 了解Java虚拟机的内存模型,有助于我们明白为什么会发生线程安全问题. 上面这幅图是<深入理解Java虚拟机-JVM高级特性与最佳实践>的书中截图. 线程共享的变量 ...

  2. java 工作内存

    所谓线程的“工作内存”到底是个什么东西?有的人认为是线程的栈,其实这种理解是不正确的.看看JLS(java语言规范)对线程工作 内存的描述,线程的working memory只是cpu的寄存器和高速缓 ...

  3. Java设计模式之职责型模式总结

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6548127.html 所谓职责型模式,就是采用各种模式来分配各个类的职责. 职责型模式包括 ...

  4. Ehcache计算Java对象内存大小

    在EHCache中,可以设置maxBytesLocalHeap.maxBytesLocalOffHeap.maxBytesLocalDisk值,以控制Cache占用的内存.磁盘的大小(注:这里Off ...

  5. [ 转载 ] Java Jvm内存介绍

    一.基础理论知识 1.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序.程序开始执行时他才运行,程序结束时他就停止.你在同一台机器上 ...

  6. 关于Java虚拟机内存原型的基本知识

    Java虚拟机内存原型的六个部分: 1.寄存器:我们在程序中无法控制 2.栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 3.堆:存放用new产生的数据 4.静态域:存放在 ...

  7. Java 堆内存和栈内存

    看了一些别人总结的博客,感觉对堆内存和栈内存有了一个初步的认识.所以来写写自己对堆内存和栈内存的理解. Java把内存分成两种,一种叫做栈内存,一种叫做堆内存. 在函数中定义的一些基本类型的变量和对象 ...

  8. Java的内存分配机制

    Java程序运行在JVM(Java  Virtual Machine,Java虚拟机)上,可以把JVM理解成Java程序和操作系统之间的桥梁,JVM实现了Java的平台无关性,由此可 见JVM的重要性 ...

  9. 深入剖析Java虚拟机内存结构

    深入剖析Java虚拟机内存模型 JVM整体架构 JVM整体架构如下: 通过编写代码来分析整个内存区域 public class Math { public static final Integer C ...

随机推荐

  1. Java和Android开发IDE---IntelliJ IDEA使用技巧(转)

    以前一直使用的是Eclipse,听别人介绍说IDEA非常不错,也为了以后转Android studio铺垫下.就开始尝试用idea来开发. 这篇文章主要学习了idea的使用技巧. IDEA 全称 In ...

  2. stringstream字符串流

    例题详解 題目:输入的第一行有一个数字 N 代表接下來有 N 行資料,每一行資料里有不固定個數的整數(最多 20 個,每行最大 200 個字元),請你寫一個程式將每行的总和印出來. 輸入: 3 1 2 ...

  3. Turn the corner (三分)

    Turn the corner Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...

  4. 学习pthreads,给线程传递多个參数

    上篇博文中.boss线程给其它线程传递的仅仅有一个參数,那么假如是多个參数呢?怎么传递呢?也许你会有这种疑问,带着这个疑问,我们进入本文的世界,这里传递多个參数,採用结构体,为什么呢?由于结构体里能够 ...

  5. 2013杭州网络赛D题HDU 4741(计算几何 解三元一次方程组)

    Save Labman No.004 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  6. HDU3853-LOOPS(概率DP求期望)

    LOOPS Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Total Su ...

  7. c++ primer plus 习题答案(6)

    p425.1 #include<iostream> #include<cstring> #include<cstdlib> using namespace std; ...

  8. 【转载】Qt中的QString,QByteArray,Qchar, char*

    先要说的是QString.         之所以把QString单独拿出来,是因为string是很常用的一个数据结构,甚至在很多语言中,比如JavaScript,都是把string作为一种同int等 ...

  9. Android UiAutomator 自动化测试环境搭建---新手1

    1.首先需要准备的工具有 1.java jdk 2. android开发工具 adt 3.ant 安装包(如果下载adt里面有) 2.首先安装java环境,jdk这个百度就可以了. 3.android ...

  10. MVC-04 视图(1)

    不可否认的,View应该是整个ASP.NET MVC项目开发过程中最花时间的部分,因为与显示逻辑相关的技术五花八门,你可能要学习的有HTML.CSS.JavaScript.DOM.JQuery.JSO ...