java并发内存模型

时间:2022-04-28 13:23:05

java中线程之间的共享变量存储在主内存(java堆)中,每个线程都有一个私有的本地内存,本地内存存储了该线程以读、写共享变量的副本。本地内存是一个抽象概念,并不真实存储。它涵盖了cache,寄存器记等等。

线程之间的通信

线程之间的通信采用的是共享内存的方式,整个通信的过程由JMM(java内存模型)来控制的。线程A与线程B之间要通信必须要经历下面两个过程:

  • 线程A把本地内存A中更新过的共享变量刷新到主内存中去
  • 线程B到主内存中读取线程A之前已更新过的共享变量

重排序

java编译器/解释器为了优化程序代码重排序。我们先来看一个例子:

public class Test {
    static boolean flag = true;
    static float money = 0f;
    public static void main(String[] args) {
        flag = false;
        money = 0.5f;
        new Thread() {
            @Override
            public void run() {
                test();
            }
        }.start();
    }

    static void test() {
        while (!flag)
            Thread.yield();
        System.out.println("money == " + money);
    }
}

上面的代码要么输出"money==0.5"(几率很小很小),要么什么都不输出。这是因为编译器可能将flag = false和money = 0.5f进行的重排序。即money = 0.5f出现在了flag=false的前面。这样的话,当mony=0.5f时发生了线程切换,test方法得到了执行。而这是flag值是为true的,所以输出了"money == 0.5"。那么这样的话,我们写的代码得不到控,是不是很无奈。不用担心,JMM提出了happens-before机制。

happens-before

hanppens-before是JMM对程序员做出的保证的。

在一个线程中前一个操作对后一个操作是可见的

a=3;
a=5;

这种操作是前后有依赖性的。先a赋值为3,后又改成5。不管这两行代码将来重排序后,前后顺序发生如何变化,JMM对程序员做出的保证是a=3先执行,a=5后执行。但是向a=3,b=6; 这种前后没有依赖关系的就不能保证执行顺序了。

同一个对象的解锁操作,对其加锁是可见的

加锁和解锁多发生于多线程中,如果对一个对象进行的解锁操作,那么对这个对象的加锁操作一定是可见的。意思是对一个对象的进行解锁操作,则对该对象进行加锁操作时一定能加锁成功的。

如果A happens-before B,且B happens-before C,那么A happens-before C

volatile字段的写入操作happens-before于每一个后续的同一个字段的读操作

java并发内存模型的更多相关文章

  1. 掌握Java的内存模型,你就是解决并发问题最靓的仔

    摘要:如果编写的并发程序出现问题时,很难通过调试来解决相应的问题,此时,需要一行行的检查代码,这个时候,如果充分理解并掌握了Java的内存模型,你就能够很快分析并定位出问题所在. 本文分享自华为云社区 ...

  2. java线程内存模型,线程、工作内存、主内存

    转自:http://rainyear.iteye.com/blog/1734311 java线程内存模型 线程.工作内存.主内存三者之间的交互关系图: key edeas 所有线程共享主内存 每个线程 ...

  3. Java虚拟机内存模型及垃圾回收监控调优

    Java虚拟机内存模型及垃圾回收监控调优 如果你想理解Java垃圾回收如果工作,那么理解JVM的内存模型就显的非常重要.今天我们就来看看JVM内存的各不同部分及如果监控和实现垃圾回收调优. JVM内存 ...

  4. C++11并发内存模型学习

    C++11标准已发布多年,编译器支持也逐渐完善,例如ms平台上从vc2008 tr1到vc2013.新标准对C++改进体现在三方面:1.语言特性(auto,右值,lambda,foreach):2.标 ...

  5. java String 内存模型

    关于java的内存模型,参照以下的一篇文章: https://isudox.com/2016/06/22/memory-model-of-string-in-java-language/

  6. Java虚拟机--内存模型与线程

    Java虚拟机--内存模型与线程 高速缓存:处理器要与内存交互,如读取.存储运算结果,而计算机的存储设备和处理器的运算速度差异巨大,所以加入一层读写速度和处理器接近的高速缓存来作为内存和处理器之间的缓 ...

  7. Java对象内存模型

    2 Java对象内存模型 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header). 实例数据(Instance Data)和对齐填充(Padding). 在 JVM ...

  8. Java的内存模型

    "让计算机并发执行若干个运算任务"与"更充分地利用计算机处理器的效能"之间的因果关系,看起来顺理成章,实际上它们之间的关系并没有想象中的那么简单,其中一个重要的 ...

  9. Java多线程内存模型

    Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果.在此之前 ...

随机推荐

  1. STL容器

    啦啦啦,今天听啦高年级学长讲的STL容器啦,发现有好多东西还是有必要记载的,毕竟学长是身经百战的,他在参加各种比赛的时候积累的经验可不是一天两天就能学来的,那个可是炒鸡有价值的啊,啊啊啊啊啊 #inc ...

  2. 【转】IOS高级教程1:处理1000张图片的内存优化

    转载请保留以下原文链接: http://my.oschina.net/taptale/blog/91894 一.项目需求 在实际项目中,用户在上传图片时,有时会一次性上传大量的图片.在上传图片前,我们 ...

  3. 实用图像处理入门 - 2 - Windows平台下编译openCV

    标签中的部分 font-family: 华文细黑; font-size: 26px; font-weight: bold; color: #611427; margin-top:40px; } h2 ...

  4. HDU-1395 2^x mod n = 1

    http://acm.hdu.edu.cn/showproblem.php?pid=1395 怎样取余是关键.. 2^x mod n = 1 Time Limit: 2000/1000 MS (Jav ...

  5. Android得知Scroller(两)——ViewGroup转让scrollTo()

    MainActivity例如下列: package cc.ac; import android.os.Bundle; import android.view.View; import android. ...

  6. MAT(Memory Analyzer Tool)使用心得

    起因:最近在跟踪产品的性能问题,期间主要问题体现在JVM的内存回收问题,使用MAT工具进行JVM内存分析(也可对android 的应用内存分析) 问题描述: 1.部分后端服务在运行一段时间后会突然年老 ...

  7. 2159 ACM 杭电 杀怪 二维费用的背包+完全背包问题

    题意:已知经验值,保留的忍耐度,怪的种数和最多的杀怪数.求进入下一级的最优方案. 思路:用二维费用的背包+完全背包问题 (顺序循环)方法求解 什么是二维费用的背包问题? 问题: 二维费用的背包问题是指 ...

  8. asp.net core 通过ajax上传图片及wangEditor图片上传

    asp.net core 通过ajax上传图片 .net core前端代码,因为是通过ajax调用,首先要保证ajax能调用后台代码,具体参见上一篇.net core 使用ajax调用后台代码. 前端 ...

  9. notepad 正则表达式 复制 文本

  10. Codeforces 958C3 - Encryption (hard)

    C3 - Encryption (hard) 思路: 记sum[i]表示0 - i 的和对 p 取模的值. 1.如果k * p > n,那么与C2的做法一致,O(k*p*n)复杂度低于1e8. ...