如果要了解Java内存模型,就得对多线程的三大特性有初步的了解。

1、原子性:独一无二、一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。比如i = i+1;其中就包括,读取i的值,计算i,写入i。这行代码在Java中是不具备原子性的,则多线程运行肯定会出问题,所以也需要我们使用同步和lock这些东西来确保这个特性了。原子性其实就是保证数据一致、线程安全。

2、可见性:当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够“立即”看得到修改的值。若两个线程在不同的cpu,那么线程1改变了i的值还没刷新到主存,线程2又使用了i,那么这个i值肯定还是之前的,线程1对变量的修改线程没看到这就是可见性问题。

3、有序性:主要是用于线程间的通讯,比如join、wait等操作。

共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入时,能对另一个线程可见。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。

从上图来看,线程A与线程B之间如要通信的话,必须要经历下面2个步骤:

1. 首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。

2. 然后,线程B到主内存中去读取线程A之前已更新过的共享变量。

下面通过示意图来说明这两个步骤:

如上图所示,本地内存A和B有主内存中共享变量x的副本。假设初始时,这三个内存中的x值都为0。线程A在执行时,把更新后的x值(假设值为1)临时存放在自己的本地内存A中。当线程A和线程B需要通信时,线程A首先会把自己本地内存中修改后的x值刷新到主内存中,此时主内存中的x值变为了1。随后,线程B到主内存中去读取线程A更新后的x值,此时线程B的本地内存的x值也变为了1。

从整体来看,这两个步骤实质上是线程A在向线程B发送消息,而且这个通信过程必须要经过主内存。JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证。

总结:什么是Java内存模型:java内存模型简称jmm,定义了一个线程对另一个线程可见。共享变量存放在主内存中,每个线程都有自己的本地内存,当多个线程同时访问一个数据的时候,可能本地内存没有及时刷新到主内存,所以就会发生线程安全问题。

注意:Java内存模型和Java内存结构不是一个概念,切记切记

Java多线程之Java内存模型的更多相关文章

  1. JAVA多线程之volatile 与 synchronized 的比较

    一,volatile关键字的可见性 要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下: 从图中可以看出: ①每个线程都有一个自己的本地内存空间--线程栈空 ...

  2. Java多线程之ConcurrentSkipListMap深入分析(转)

    Java多线程之ConcurrentSkipListMap深入分析   一.前言 concurrentHashMap与ConcurrentSkipListMap性能测试 在4线程1.6万数据的条件下, ...

  3. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

  4. java多线程之yield,join,wait,sleep的区别

    Java多线程之yield,join,wait,sleep的区别 Java多线程中,经常会遇到yield,join,wait和sleep方法.容易混淆他们的功能及作用.自己仔细研究了下,他们主要的区别 ...

  5. Java多线程之Runnable与Thread

    Java多线程之Thread与Runnable 一.Thread VS Runnable 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类和 ...

  6. JAVA多线程之UncaughtExceptionHandler——处理非正常的线程中止

    JAVA多线程之UncaughtExceptionHandler——处理非正常的线程中止 背景 当单线程的程序发生一个未捕获的异常时我们可以采用try....catch进行异常的捕获,但是在多线程环境 ...

  7. java多线程之wait和notify协作,生产者和消费者

    这篇直接贴代码了 package cn.javaBase.study_thread1; class Source { public static int num = 0; //假设这是馒头的数量 } ...

  8. Java线程之Java内存模型(jmm)

    一.Java内存模型(jmm) 线程通信 消息传递 重排序 顺序一致性 Happens-Before As-If-Serial

  9. java多线程之Concurrent包

    1.在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题. 2.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的 ...

随机推荐

  1. [ Pytorch ] torch.squeeze() 和torch.unsqueeze()的用法

    squeeze的用法主要就是对数据的维度进行压缩或者解压. squeeze() torch.squeeze(a):去掉a中维数为1的维度. a.squeeze(N):去掉特定维度N下维数为1的维度. ...

  2. elasticsearch 自定义routing

    由于线上elasticsearch集群数据量越来越大,优化已经已经是重中之重. 优化的方式有很多中,网上一大堆,自行百度. 优化方案中有个叫routing的方案是个需要熟悉业务日志才能使用.于是我就研 ...

  3. Lesson 13 The search for oil

    What do oilmen want to achieve as soon as they strike oil? The deepest holes of all are made for oil ...

  4. Linux之系统优化配置

    Linux系统优化配置 更新国内镜像源 国内速度快的常用更新源如下: ​ http://mirrors.sohu.com ​ http://mirrors.163.com [root@greymous ...

  5. python join 和setDaemon 简介

    Python多线程编程时,经常会用到join()和setDaemon()方法 1.join ()方法:主线程A中,创建了子线程B,并且在主线程A中调用了B.join(),那么,主线程A会在调用的地方等 ...

  6. 新闻网大数据实时分析可视化系统项目——2、linux环境准备与设置

    1.Linux系统常规设置 1)设置ip地址 使用界面修改ip比较方便,如果Linux没有安装操作界面,需要使用命令:vi /etc/sysconfig/network-scripts/ifcfg-e ...

  7. 五、java基础-关键字this_static_super_abstract_final,finalize()方法finally语句块

    1.关键字this 含义:this 是一个引用类型,代表当前对象,引用类型里面必然保存内存地址,在堆中的每个对象中存储,保存内存地址指向自身. 用法: 1)this可以用在成员方法中,里面保存内存地址 ...

  8. PAT B1019/A1069 数字黑洞

    给定任一个各位数字不完全相同的四位正整数,如果先把四个数字按照非递增排序,再按照非递减排序,然后用第一个数字减第二个数字,将得到一个新的数字,一直重复这样做,很快就会停在有“数字黑洞”之称的6147, ...

  9. 微信内置浏览器video标签自动全屏的问题

    微信打开h5video视频的时候都会自动全屏播放,有时候影响用户体验 要禁止自动全屏就要加这几个属性 'x5-playsinline':'true', 'webkit-playsinline':'tr ...

  10. Link Analysis_1_Basic Elements

    1. Edge Attributes 1.1 Methods of category 1.1.1 Basic three categories in terms of number of layers ...