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.
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/axman/archive/2006/08/19/1097541.aspx
分享到:
相关推荐
在Java面试中,对于高级职位,面试官通常会考察应聘者对Java语言的深入理解和在高并发环境下的处理能力。以下是一些相关的知识点: 1. **JVM内存模型**:了解Java虚拟机(JVM)的工作原理至关重要。JVM内存分为堆...
《深入理解Java虚拟机》是一本深度探讨Java虚拟机(JVM)的著作,涵盖了JVM性能调优、内存模型以及虚拟机原理等多个关键领域。本文将基于这些主题,详细阐述其中的重要知识点。 首先,我们要了解Java虚拟机(JVM)...
重点理解对象的创建、垃圾回收、内存泄漏等问题。 4. **垃圾收集**:Java的自动内存管理主要依赖垃圾收集,包括分代收集、标记-清除、复制、标记-整理和局部GC等算法。理解GC的工作原理和调优技巧,可以有效地避免...
通过《深入JAVA虚拟机第二版》的学习,开发者不仅可以提升对Java技术的掌握,还能深入理解程序运行的本质,这对于编写高效、稳定、可维护的Java应用程序至关重要。此外,书中还会涉及到最新的JVM特性,帮助读者...
1. **Java内存模型**:深入解析了JMM(Java Memory Model),它是多线程环境下保证数据一致性的重要机制。 2. **JVM性能调优**:介绍了如何通过监控和调整JVM参数来优化应用程序的性能。 3. **JNI(Java Native ...
《深入学习:Java多线程编程》是一本专注于Java并发技术的专业书籍,旨在帮助开发者深入理解和熟练运用Java中的多线程编程。Java多线程是Java编程中的核心部分,尤其在现代高性能应用和分布式系统中不可或缺。理解并...
这123道试题涵盖了Java并发编程的各个方面,旨在帮助开发者深入理解和应用Java的高并发API。 一、Java并发基础 1. 线程与进程:了解线程和进程的区别,以及它们在并发执行中的作用。 2. 线程的创建:掌握通过Thread...
《深入Java内存模型》是一本面向Java开发人员的专业书籍,旨在帮助读者深入理解Java平台的内存管理和性能优化。这本书详细探讨了Java内存模型(JVM)的基础知识,以及如何利用这些知识来提升程序的效率和稳定性。...
对于Java开发者来说,深入理解JVM的工作原理和机制是提高代码质量和性能的关键。本文将详细探讨三篇关于Java虚拟机的论文,这些论文从不同的角度,深入剖析了JVM的内部机制,性能优化策略,以及内存管理技术。 首先...
重点掌握volatile、final关键字的作用,了解happens-before原则,以及线程间的内存屏障。此外,还需理解内存泄漏和垃圾回收机制,确保程序的内存效率。 3、JVM调优案例式实战化指导 JVM作为Java程序的运行平台,其...
首先,面试者需要对Java的基础语法有深入理解,如变量、数据类型、运算符、流程控制语句(if、switch、for、while)、方法和类。此外,还要熟悉封装、继承、多态这三大面向对象特性,以及抽象类、接口、内部类等概念...
此外,深入理解类加载机制、垃圾回收(GC)以及内存管理也是面试中常见的问题。 其次,深入理解Java集合框架至关重要。ArrayList、LinkedList、HashMap、HashSet等容器的内部实现、操作性能以及适用场景需要清晰...
《Java并发编程》这本书是Java开发者深入理解和掌握并发编程的重要参考资料。并发编程是现代多核处理器环境下提升程序性能的关键技术,对于大型系统和高并发应用的开发至关重要。Java平台提供了丰富的并发工具和机制...
在并发编程中,掌握底层原理对于优化...在面试中,这些知识点往往是判断开发者是否具备深入理解和实践经验的重要标志。掌握并发编程不仅需要理论知识,还需要通过实践不断磨练和提升沟通能力,以精准地理解和解决问题。
这本书与《深入理解Java虚拟机》齐名,为Java开发者提供了理解和掌握并发编程的宝贵资源。在Java开发中,尤其是在高并发场景下,理解和应用并发编程技巧是提高系统性能和稳定性的重要手段。 并发编程是现代多核...
此外,Java内存模型(JMM)以及线程间的通信方式(如wait/notify、join、CountDownLatch等)也常常是考察的重点。 对于高级主题,如设计模式,面试者应能熟练应用单例、工厂、观察者、装饰器、代理等常见设计模式,...
链表、栈、队列、堆、树、图等各种数据结构的实现和应用,以及排序(如快速排序、归并排序、冒泡排序等)、查找(如二分查找、哈希查找)等算法,都需要深入理解并能够灵活运用。面试中可能会让你现场编写或分析代码...
4. **集合框架**:深入理解ArrayList、LinkedList、HashSet、HashMap等集合类的内部实现和使用场景,以及如何优化它们的性能。 5. **并发编程**:掌握线程的基本操作,如创建线程、线程同步(synchronized关键字、...
1. **算法与数据结构**:深入理解并掌握快速排序、平衡二叉树、红黑树、哈希表等高级数据结构和算法,这对于提升代码质量和解决复杂问题至关重要。 2. **并发编程**:讲解多线程编程的基础概念,包括Java内存模型...