`

Java多线程高并发进阶篇(一)-volatile实现原理剖析

阅读更多

我们知道,在JVM的类加载机制中,是将外围的源码文件编译成字节码文件(.class)后加载到JVM中,然后Java通过执行引擎执行字节码,最终转化为汇编指令由CPU执行.我们说的并发编程机制,当然离不开JVM的实现和CPU的指令集.

了解JMM(Java Memory Model,Java内存模型)都知道,JMM是围绕着原子性,有序性,可见性展开的.后面我会专门写一篇,阐述Java内存模型以及它与处理器内存模型,以及顺序一致性内存模型的关系.

1.volatile的定义

在Java语言规范中,对volatile的定义如下:

Java编程语言允许线程访问共享变量,为了确保共享变量能准确的访问一致性的更新,线程应该确保通过排它锁单独获得这个变量,因此Java语言提供了volatile.如果一个变量被定义为volatile,那么Java线程的内存模型(也叫线程的本地内存)看到这个变量的内容是一致的.换句话说,Java语言提供volatile,是为了保证线程之间共享变量的可见性.

 

2.volatile的实现原理

在了解volatile之前,我们需要明白CPU中的一些专业术语.


 

在了解了上面的专业术语后,我们就了解下volatile如何保证可见性.

有volatile修饰的共享变量在进行写操作时,转变成汇编指令时,会多出一行lock addl $0×0,(%esp);

 

lock前缀指令在多核处理器下会引发两件事情:

①将当前处理器缓存行的数据全部写回到系统内存(JMM中的主内存).

②在这个写回主内存的操作会使在其他处理器(CPU)中缓存了该内存地址的数据无效.

这里我们解释一下.

为了提高处理速度,处理器不直接和主内存进行通信,而是先将主内存的数据读取到处理器的内部缓存中(一级或二级缓存或其他).如果对声明了volatile的变量进行写操作,JVM就会向处理器发送一条lock前缀的指令,如红色字体部分,然后将这个变量所在的缓存行数据写回到主内存.如果其他处理器缓存的该共享变量的值还是旧的,那么后续的操作就会有问题.因此,在多处理器情况下,为了保证各个处理器缓存该共享变量的内容一致,就需要根据缓存一致性协议,每个处理器通过嗅探总线上传播的数据来检查自己的缓存行是否过期了,如果发现过期了,就会把自身存储该共享变量的缓存行置为无效状态,当处理器需要对这个数据进行修改操作时,那么就需要去主内存重新读取这个共享变量的值,此时当然读取到的是上一个处理器修改过的内容了.

 

3.关于volatile实现原理两条原则的详述

在2中,我们说到了lock指令在多处理器情况下引发的两件事情.我们来具体介绍下这两件事情.

①lock指令会引起理器存回写到内存

旧型号的处理器中,Lock前缀指令执行期间,会声言一个LOCK#信号,该信号确保处理器在指令执行期间,可以独占共享内存(也就是主内存).当一个处理器在总线上声言LOCK#信号时,其他处理器的请求将会被阻塞.这种方式叫"总线锁"

但是在最新型号的处理器中,不再使用LOCK#信号锁总线,而是锁缓,因为锁总线的开销太大了.如果处理器访问的内容已经缓存在处理器内部,它会锁定该内容所在的内存区域的缓存行,并将该缓存行内容写回到共享内存(也就是主内存),并使用缓存一致性协议保证修改的原子性,这个过程叫做"缓存锁定".

这里要说明一点:存一致性机制会阻止同修改由两个以上理器存的内存区域数据。

一个理器的存回写到主内存会致其他理器的存无效

在处理器中,使用MESI(修改,独占,共享,无效)控制协议 ,去维护处理器内部的缓存和其他处理器的缓存一致性.在多核处理器系统中,处理器能嗅探到其他处理器访问主内存以及它们的内部缓存.处理器使用嗅探技术保证它的内部缓存,主内存,其他处理器的缓存的数据跟总线上保持一致.

比如,PentiumP6 family理器中,如果一个器通过嗅探检测到其他理器打算将共享变量回写到主内存地址,那么个地址对于缓存了该数据缓存行的处理器来说于共享状态,这个处理器就会把自身处理器缓存中对应的缓存数据行置为无效状态.

 

来一张图,让蒙圈的小伙伴们醒醒.JMM的内存结构示意图.



 

  • 大小: 164.1 KB
  • 大小: 53.3 KB
分享到:
评论

相关推荐

    java多线程进阶

    这本书“java多线程进阶”显然旨在帮助读者深化这方面的理解,打通编程中的“任督二脉”,使开发者能够更加熟练地在并发环境中编写高效且稳定的代码。 1. **线程基础**:书中首先会介绍Java多线程的基础知识,包括...

    Java进阶高手课-并发编程透彻理解

    在项目实战部分,学员将有机会应用所学知识解决实际问题,如构建高并发的Web服务,或者设计并实现一个分布式任务调度系统。实战项目可以帮助巩固理论知识,提升解决实际问题的能力。 总之,"Java进阶高手课-并发...

    北大计算机系JAVA培训讲义(进阶篇)

    1. **多线程**:Java提供了丰富的多线程支持,包括Thread类和Runnable接口,以及synchronized关键字、volatile变量、Lock接口等同步机制。学习者将了解如何创建和管理线程,以及如何处理并发问题,如死锁、活锁和...

    多线程终极案例程序(多线程进阶)

    在IT行业中,多线程是Java编程中一个重要的高级特性,尤其对于开发高效能和响应迅速的应用至关重要。这个“多线程终极案例程序”...通过学习和实践这个案例,开发者可以深入理解Java多线程并提高解决实际问题的能力。

    JSR133中文版,java并发进阶必读

    JSR133是Java并发编程领域的一个里程碑,它通过增强内存模型,提高了多线程环境下的程序正确性和性能。对于希望在Java并发领域进一步提升的开发者来说,深入学习JSR133中文版是至关重要的。通过理解并应用其中的理论...

    Java语言程序设计进阶篇

    ### Java语言程序设计进阶知识点解析 #### 一、Java语言概述 - **定义与特点**:Java是一种广泛使用的高级编程语言,由Sun Microsystems在1995年首次发布。它具有面向对象、平台无关性、健壮性、安全性等特点。 - ...

    java并发编程1-9章

    通过阅读这些章节,我们可以深入了解Java平台上的多线程和并发处理机制,这对于任何需要处理高性能、高并发系统开发的Java程序员来说都至关重要。 首先,第一章通常会介绍并发编程的基础概念,包括线程的基本操作,...

    JAVA并发编程实践

    - **并发集合**:`ConcurrentHashMap`、`CopyOnWriteArrayList`等集合类在高并发场景下提供更好的性能和安全性。 - **阻塞队列**:`ArrayBlockingQueue`、`LinkedBlockingQueue`等阻塞队列为多线程之间共享数据提供...

    JAVA并发编程实战.pdf

    - **Happens-Before原则**:Java内存模型规定了一系列规则来保证多线程程序的正确执行顺序,其中最重要的是“发生先于”(Happens-Before)原则。 #### 2. 原子性 - **Atomic类**:Java提供了`java.util.concurrent....

    【BAT必备】多线程面试题

    CAS(Compare and Swap)是一种无锁算法,在不使用锁的情况下实现多线程之间的变量同步。其工作原理是:比较变量的期望值和实际值是否一致,如果一致,则更新为新值;如果不一致,则不做任何操作。 #### 三、实战...

    Java进阶知识点汇总.pdf

    - **volatile**:用于修饰共享变量,确保多线程环境中的可见性和有序性,但不保证原子性。 - **synchronized**:用于实现同步控制,可以修饰方法或代码块,保证同一时间只有一个线程执行该段代码。 - **import**:...

    java面试大全从入门到入职

    - volatile和Atomic类:理解它们在多线程环境下的作用和原理。 5. **设计模式** - 工厂模式、单例模式、观察者模式等常见的设计模式,以及何时、何地使用它们。 - 掌握面向切面编程(AOP)的基本概念,了解...

    《Java技术指南2019》

    该书分为基础篇、进阶篇、高级篇、架构篇和拓展篇五个部分,覆盖了Java编程的多个层面,包括Java虚拟机(JVM)的深入理解、Java基础语法、并发编程、网络编程以及最新的Java技术动态。书中还推荐了一系列的参考书籍...

    疯狂java讲义源码

    - Runnable接口:实现多线程的另一种方式,适合资源的共享。 - synchronized关键字:用于线程同步,避免并发访问同一资源引发的问题。 - volatile关键字:保证多线程环境下变量的可见性和有序性。 6. **输入输出...

    2023黑马面试宝典-Java面试宝典大全-java面试宝典黑马

    4. **多线程**:Java提供了丰富的多线程支持,面试中会考察线程的创建、同步机制(synchronized、Lock)、死锁、线程池等。理解线程状态转换图,掌握线程安全问题的解决方案,如volatile、ThreadLocal等,有助于在...

    狂神说笔记,个人觉得不赖

    【Java 开发】是计算机编程领域的一个重要分支,主要用于构建桌面应用、服务器端应用以及大型分布式系统的后端服务。...通过深入学习,你将能熟练掌握Java多线程编程,为构建高性能、高并发的Java应用打下坚实基础。

    Java基础及高级学习笔记.zip

    最后,"Java多线程&高并发.docx"和"Java开发.xmind"文件将带你进入Java并发的世界: 1. **线程基础**:创建和管理线程,理解线程同步和协作机制,如synchronized关键字、volatile变量、Lock接口和条件变量。 2. **...

    Java 面试宝典 - v1.1

    Java的多线程编程是面试中的一大挑战。你需要掌握线程的创建、同步机制(synchronized、volatile、Lock等)、死锁、活锁以及线程池的使用。 五、IO与NIO 理解传统IO和NIO的区别及其应用场景,熟悉BufferedReader、...

    JAVA核心技术--高级特征(第八版)--第四部分

    1. **多线程与并发**:Java以其强大的并发支持而闻名。这部分可能详细讲解了`java.util.concurrent`包中的工具类,如`ExecutorService`、`Future`、`Callable`、`ThreadLocal`,以及如何使用`synchronized`关键字和`...

Global site tag (gtag.js) - Google Analytics