`
javaG
  • 浏览: 553141 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

深入理解JMM

阅读更多

深入理解JMM的重点

JMM具体规定要JLS的 "Thread and lock"一章中,可以说这是一章非常晦涩的一个规范,要想完全把
它理解清楚,一般的辛苦是不行的.那是要"相当的~~~"的辛苦.而要把它向别人再解释清楚,那简直就
是恶梦.

作者自知无力能全面清楚地向大家说明这一章的内容,但以作者的经验,主要从以下两个方面去理解
可以改快地抓住本质.而不至于陷入"Thread and lock"的泥潭.

一.理解主存储区和线程工作存储区.二.理解同步的两个功能.

首先要明白的问题:
1.多个线程共有的字段应该用synchronized或volatile来保护.
2.synchronized负责线程间的互斥.即同一时候只有一个线程可以执行synchronized中的代码.
3.volatile负责线程中的变量与主存储区同步.但不负责每个线程之间的同步.

[Main Memory]与[Working Memory]
Main Memory是实例所在的存储区,所有实例和实例的字段都在此区域,为所有线程所共有.
Working Memory是绺个线程独自所拥有的存储区.其中有Main Memory中部分COPY.

这两个存储区只在JVM内部与物理存储区无关.


如何理解Main Memory 与Working Memory.

 设想两个棋手要通过两个终端显示器(Working Memory)对奕,而观众要通过服务器大屏幕(Main Memory )
观看他们的比赛过程.这两个棋手相当于是同步中的线程,观众相当于其它线程.

 棋手是无法直接操作服务器的大屏幕的.他只能看到自己的终端显示器,只能先从服务器上将当前
结果先COPY到自己的终端上,然后在自己的终端上操作.将操作的结果记录在终端上,然后在某一时刻同步到
服务器上.他所能看到的结果就是从服务器上COPY到自己的终端上的内容,而要想把自己操作后的结果让其他
人看到必须同步到服务器上才行.至于什么时候同步,那要看终端和服务器的通信机制.

为什么要规定这么复杂的规范?因为要预留JVM的优化空间,如果规定所有的计算结果必须同步到主存储区,
那么对于方法中的计算顺序,赋值顺序等就没有优化的可能了.
引用字段:
 线程在引用字段时不能直接从Main Memory中引用(JAVA1.2以前如此),如果Working Memory中没
有该字段,则会从Main Memory中将该字段COPY到Working Memory中,这个过程为read-load,完成后线程会
引用该COPY.
 当同一线程再度引用该字段时,有可能重新从Main Memory中获取COPY(read-load-use),也有可能
直接引用原来的COPY(use),也就是说 read,load,use顺序可以由JVM实现系统决定.

字段赋值:
 线程在字段赋值时不能直接为Main Memory中字段赋值(JAVA1.2以前如此),线程会将值指定给Working
Memory中的字段COPY(assign),完成后这个COPY会同步到主存储区(store-write),至于何时同步过去,根据JVM
实现系统决定.
有该字段,则会从Main Memory中将该字段COPY到Working Memory中,这个过程为read-load,完成后线程会
引用该COPY.
 当同一线程多次重复对字段赋值时,比如:
 for(int i=0;i<100;i++)
  filldX = .....;
线程有可能只对Working Memory中的COPY进行赋值,只到最后一次赋值后才同步到主存储区.
所以assign,store,weite顺序可以由JVM实现系统决定.


JLS规定了6 个action,为最小操作单位,它们是原子的(atomic),JLS规定了这6个操作必须的顺序,但这个规定
是一个粗范围的,具体实现的JVM可以在这个范围内精心设计按自己的方式排序来达到最优:
 [read和write] 完成将字段从Main Memory COPY到Working Memory 和从 Working Memory COPY到
        Main Memory.
 [use和assign] 指示线程需要从Main Memory引用字段 和 需要为Main Memory中字段赋值.
 [lock和unlock] 表示线程获取锁和释放锁.

 

[synchronized 两个功能]

synchronized 方法 与同步块.

所有synchronized方法 最终还是同步块.
非静态的synchronized 方法相当synchronized (this){方法内容}
静态的synchronized 方法相当synchronized (XXX.clsss){方法内容}

所以我们把synchronized方法合并为同步块.

当线程要进入synchronized时,Working Memory中所有没有同步到Main Memory结果会强制store-write,然后
Working Memory会被clear.那么只要再有对字段的引用当然会先read-load.

当线程要退出synchronized时,必须执行store-write,即把Working Memory中的结果同步到Working Memory中,但
退出synchronized后线程可以继续引用Working Memory中的COPY.

所以,线程在进入和退出synchronized时都把Mian Memory与Working Memory中的字段同步.
但在synchronized外和synchronized中,何时进行Mian Memory与Working Memory中的字段同步是不确定的.

大家已经非常明白这里说的"同步"是指Mian Memory与Working Memory中字段值的"一致".即内存同步,而不是指
synchronized本身的"互斥"的意思.

加上前面所介绍的 volatile,我们知道如果要完成Mian Memory与Working Memory中字段值的"一致",只有线程进入
或退出synchronized时,或字段是volatile时才能保证,其它的情况下,JAVA还没有方法保证.

随着JVM版本的更新,以及关于JMM的JSR版本更新,JMM的修改完善会使不同时期有不同的表现,但这些修改都是为了
修复完善JLS中的规范,JAVA是向前兼容的.前面的规范本身一般不会被修改.所以掌握上面这些重点知识后,可以再
详细研究JLS的"Thread and lock"和具体的JSR.

分享到:
评论

相关推荐

    01-并发编程之深入理解JMM&并发三大特性(一).pdf

    在深入理解Java内存模型(JMM)及并发三大特性方面,我们需要先建立对多线程、共享内存模型、可见性、有序性和原子性的基础概念。Java内存模型是Java并发编程的核心,它定义了共享变量在多线程环境中的行为规则和...

    【并发编程】深入理解JMM.pdf

    ### 并发编程深入理解——基于JMM的记忆模型解析 #### 一、基本概念与并发编程基础 在深入了解Java内存模型(JMM)之前,我们首先需要掌握一些基本的并发编程概念,这包括进程、线程以及并行与并发的区别。 1. **...

    深入Java内存模型-JMM

    深入理解JMM对于编写高效、正确的并发程序至关重要。通过合理利用JMM提供的工具和机制,开发者可以有效地解决并发编程中的诸多挑战,创建出健壮的多线程应用。阅读"深入Java内存模型.pdf"这样的资料,将有助于你更...

    14、深入理解并发可见性、有序性、原子性与JMM内存模型

    深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发...

    图灵Java高级互联网架构师第6期并发编程专题笔记.zip

    01-并发编程之深入理解JMM&并发三大特性(一)-fox 02-并发编程之深入理解JMM&并发三大特性(二)-fox 03-01-HashMap源码解析-monkey 03-并发List、Set、 ConcurrentHashMap底层原理剖析-monkey 04-Java并发线程池...

    深入理解Java内存模型(经典).rar

    深入理解JMM对于编写高效、线程安全的Java代码至关重要。 首先,我们要知道JMM解决的主要问题是线程之间的数据同步和可见性问题。在多线程环境中,每个线程都有自己的工作内存,而共享变量存储在主内存中。线程读写...

    深入理解JAVA内存模型。。

    深入理解JMM对于编写高效、可靠的并发程序至关重要。 1. **内存区域划分** Java内存模型将内存划分为不同的区域,包括程序计数器、虚拟机栈、本地方法栈、堆和方法区(在Java 8及以后版本中被元空间取代)。这些...

    深入理解JAVA内存模型.pdf

    深入理解JMM对于编写高效、安全的多线程Java程序至关重要。 1. **内存架构** Java内存模型分为三个主要区域:程序计数器、Java虚拟机栈和本地方法栈(这三个属于线程私有),堆内存以及方法区(或称为元空间)。...

    深入理解 Java 内存模型

    《深入理解 Java 内存模型》这本书由程晓明编著,旨在帮助开发者深入理解和应用 JMM。 1. **内存层次结构**:Java 内存模型将内存分为堆内存、栈内存、方法区(在 Java 8 及以后版本中被元空间替代)和程序计数器等...

    深入理解Java内存模型 pdf 超清版

    深入理解Java内存模型对于编写高效的并发程序至关重要。本文将详细介绍JMM的核心概念、工作原理以及相关的编程实践。 1. **核心概念** - **线程私有区域**: 包括程序计数器、虚拟机栈、本地方法栈,这些区域中的...

    Java内存模型分析与其在编程中的应用.zip

    最后,深入理解JMM可以帮助我们编写出更健壮的并发代码,避免出现如死锁、活锁、饥饿等并发问题。通过合理利用Java提供的并发工具类,如Semaphore、CountDownLatch、CyclicBarrier等,可以更好地控制线程间的协作和...

    美国钻石JMM-512-V512技术手册(英文).rar

    "JMM512-V512技术手册.pdf"很可能是设备的主要技术文档,详细介绍了设备的所有功能和操作方法,而"JMM512-V512简介.pdf"则可能是对设备的简明概述,适合初次接触的用户快速了解设备的基本信息。 总之,《美国钻石...

    三问JMM--有关JVM内存模型的PPT

    近期,在诚信通开源研究小组的专题学习分享会上,我们针对Java内存模型(JMM)进行了深入探讨,现将JMM相关的一些核心概念进行梳理,以便更好地理解和把握JMM的基本原理。 #### 第一问:JMM是干什么的? JMM (Java ...

    并发编程之一 日常学习笔记

    首先,"并发编程之深入理解JMM&并发三大特性",这里的JMM指的是Java内存模型(Java Memory Model),它是Java平台中的核心概念,用于规定了线程之间如何共享和访问内存中的数据。并发的三大特性包括原子性、可见性和...

    深入理解java内存模型

    这本书"深入理解Java内存模型"显然是为了帮助读者深入探讨这个主题,以便更好地理解和解决并发编程中的问题。 Java内存模型主要涉及以下几个核心概念: 1. **主内存**:所有线程共享的数据存储区域,包括类的静态...

    通过实例程序验证与优化谈谈网上很多对于Java DCL的一些误解以及为何要理解Java内存模型.doc

    总的来说,这篇文章通过实例和分析,揭示了Java DCL模式的一些常见误解,并强调了深入理解JMM对于开发高效、可靠的并发代码的重要性。通过这种方式,开发者可以更好地掌握如何在多线程环境中正确地实现单例模式。

    java内存模型(有助理解多线程)

    对于Java开发者来说,深入理解JMM是非常必要的,特别是在进行多线程编程时,它可以帮助我们更好地理解和解决多线程环境下的问题。 #### 内存模型概述 Java平台在设计之初就内置了对多线程的支持,这使得Java相比...

    第29讲Java内存模型中的happen-before1

    现并发程序的行为并不总是如预期那样,特别是在不同的处理器架构上。为了解决这些问题,Java 内存模型(JMM)应运而生,它提供了一种抽象的内存...因此,在学习并发编程时,深入理解 JMM 的原理和应用是非常必要的。

    14、深入理解并发可见性、有序性、原子性与JMM内存模型(1).pdf

    根据提供的文档信息,本文将详细解析并发编程中的关键概念——原子性、可见性及有序性,并结合Java内存模型(JMM)来深入理解这些概念。同时,我们也会通过具体示例来探讨这些问题在实际编程中的应用。 ### 一、并发...

Global site tag (gtag.js) - Google Analytics