`
yesjavame
  • 浏览: 687880 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

多线程编程 深入理解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

    并发编程中的三大特性:可见性、有序性和原子性,是多线程编程中主要的并发问题来源。这些特性是理解和规避并发编程中Bug的关键。 可见性问题是指,在多线程环境下,一个线程对共享变量的修改,其他线程可能无法...

    汪文君JAVA多线程编程实战(完整不加密)

    这本书旨在帮助Java开发者深入理解和熟练掌握多线程编程技术,提升软件开发的效率和质量。在Java平台中,多线程是并发处理的基础,对于构建高效、可扩展的系统至关重要。 Java多线程允许程序同时执行多个独立的代码...

    深入学习:Java多线程编程

    《深入学习:Java多线程编程》是一本专注于Java并发技术的专业书籍,旨在帮助开发者深入理解和熟练运用Java中的多线程编程。Java多线程是Java编程中的核心部分,尤其在现代高性能应用和分布式系统中不可或缺。理解并...

    Java多线程编程实战指南-核心篇

    《Java多线程编程实战指南-...通过《Java多线程编程实战指南-核心篇》,你可以深入了解Java并发编程的各个方面,提升在高并发场景下的编程能力。书中的案例和练习将帮助你更好地掌握理论知识,并将其应用于实际项目中。

    java 多线程编程指南

    这份“Java多线程编程指南”深入探讨了这一主题,为中级到高级的Java开发者提供了宝贵的资源。 首先,多线程的基础概念是理解整个主题的关键。线程是程序执行的最小单元,每个线程都有自己的程序计数器、虚拟机栈、...

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

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

    java多线程编程技术

    了解JMM有助于理解多线程环境下的数据一致性问题。 总之,Java多线程编程技术是每个Java开发者必备的技能。通过深入学习和实践,可以编写出高效、可靠的并发程序,充分利用现代计算机的多核处理器资源。《Java多...

    Java-jdk10-最新最全多线程编程实战指南-核心篇

    《Java-jdk10-最新最全多线程编程实战指南-核心篇》是一本深入探讨Java多线程编程的专著,针对Java 10版本进行了全面的更新和优化。这本书聚焦于Java多线程的核心概念和技术,旨在帮助开发者理解和掌握如何在并发...

    Java多线程编程核心+带目录版

    《Java多线程编程核心技术》是一本由资深Java专家倾力打造的专业著作,结合了作者10年的实战经验,深入浅出地解析了Java多线程编程的核心概念和技术。本书以丰富的案例为引导,旨在帮助读者全面理解和掌握Java平台上...

    深入理解JMM

    Java内存模型(JMM, Java Memory Model)是Java平台中用于定义如何在多线程环境下共享数据的一种规范。它规定了线程之间的交互、数据的可见性以及如何避免数据的不一致性等问题。JMM的存在主要是为了解决处理器缓存...

    多线程与高并发编程笔记、源码等

    通过这些文件,学习者可以结合理论和实践,深入理解和掌握多线程与高并发编程的精髓。 总之,这份资源是全面学习和提升多线程与高并发编程技能的宝贵材料,无论是对于初学者还是有经验的开发者,都能从中受益匪浅。...

    多线程并发编程在Netty中的应用分析

    #### JAVA内存模型与多线程编程 ##### 1.1. 硬件的发展和多任务处理 随着硬件技术的不断进步,尤其是多核处理器的普及及其成本的降低,现代操作系统几乎都具备了支持多任务处理的能力。这种能力不仅仅是为了利用...

    多线程学习汇总资料,多线程学习汇总资料,

    多线程是计算机编程中的...这个学习汇总资料将涵盖以上提到的各个知识点,通过实例解析、代码示例和经典问题分析,帮助你深入理解多线程编程,提升并发编程能力。无论你是初学者还是经验丰富的开发者,都可以从中受益。

    Java多线程知识,龙果学院

    以上只是Java多线程和并发编程的一部分基础知识,通过"Java多线程知识,龙果学院"的课程,你将能够深入了解这些概念,并通过实践提升解决并发问题的能力。同时,提供的"java并发编程视频+龙果"资料,无疑会为你的...

    并发编程之JMM&amp;amp;synchronized&amp;amp;volatile详解.pdf

    当涉及多线程和并发时,了解CPU的存储层次(如寄存器、L1、L2、L3缓存和主内存)以及它们如何影响数据的一致性和性能是至关重要的。 在并发编程中,理解这些硬件特性可以帮助开发者优化代码,利用多核CPU的优势,...

    java多线程核心技术_完整版

    Java多线程核心技术是Java开发中的重要组成部分,它关乎到...这个"Java多线程编程核心技术_完整版.pdf"教程应该涵盖了上述所有知识点,深入学习后,你将能够熟练地运用Java进行多线程编程,解决实际开发中的并发问题。

    java多线程并发实战和源码

    并发容器也是Java多线程编程中不可或缺的部分。ArrayList、LinkedList等集合类在并发环境下可能存在安全问题,因此,Java提供了并发安全的容器,如ConcurrentHashMap、CopyOnWriteArrayList和ConcurrentLinkedQueue...

    深入Java内存模型-JMM

    Java内存模型,简称JMM(Java ...通过合理利用JMM提供的工具和机制,开发者可以有效地解决并发编程中的诸多挑战,创建出健壮的多线程应用。阅读"深入Java内存模型.pdf"这样的资料,将有助于你更全面地掌握这一主题。

Global site tag (gtag.js) - Google Analytics