首页 > 系统相关 >一文读懂Java多线程并发之内存模型

一文读懂Java多线程并发之内存模型

时间:2024-06-21 16:56:32浏览次数:21  
标签:Java 变量 虚拟机 读懂 线程 内存 多线程

 什么是内存模型?

Java内存模型(Java Memory Model)描述了Java编程语言中的线程如何与内存进行交互,是和多线程相关的一组规范,需要各个 JVM 的实现来遵守 JMM 规范,以便于开发者可以利用这些规范,更方便地开发多线程程序。有了这些规范,即便同一个程序在不同操作系统的虚拟机上运行,得到的程序结果也是一致的。如果没有这些规范,不同操作系统的虚拟机对相同关键字的解释不一致,这是不可接受的。JMM旨在解决 CPU 多级缓存、处理器优化、指令重排等导致的结果不可预期的问题。

特别注意一点,Java内存模型是与多线程并发相关的规范,不是JVM内存结构。JVM内存结构讲的是JVM如何划分运行时内存区域,比如虚拟机规范将内存区域划分为堆区、方法区、虚拟机栈、本地方法栈、程序计数器五个区域。不同虚拟机可能在实现上会略有不同,但总体是按规范实现的。比如Hotspot虚拟机栈和本地方法栈是合并实现的,JDK8方法区用元空间来实现,但JDK7以下则可能是永久代来实现。

内存模型是同步关键字原理

在Java程序中,volatile、synchronized、Lock等同步关键字或锁工具类其实现原理都涉及JMM规范,或说它们就是遵循JMM规范来实现的。

比如说,我们使用volatile来修饰一个共享变量,那么这个变量在多线程环境下,数据变更会立刻从工作内存刷新回主内存以确保变量的可见性。同时,被volatile来修饰的变量也会禁止指令重排序。synchronized也有同样的效果,保证可见性,禁止指令重排序,同时会变量添加monitor对象锁,多个线程访问被synchronized修饰的变量只能等其它线程释放锁才能访问此变量。因此,synchronized能保证变量的线程安全,相当于将变量的读写串行化了,因此能保证变量的线程安全。

JMM最重要的三个东西上面基本都已提及,即原子性、可见性与指令重排序。下面我们详细了解下这几方面的内容。

什么是原子性?

在介绍Java线程的文章中也有提及,这里再次拿出来讲述一下。具备原子性的操作被称为原子操作,原子操作可以认为是一个或一组不可分割的操作,操作要么做完了,要么就都不做,不存在只做一半的情况,原子性意味着不可分割。编程界经典操作,i++,这句代码看似只有一句代码,好像很原子了,实际则不然。下面例子你觉得会打印1还是0?

public class AddTest3 {

    private static int i

标签:Java,变量,虚拟机,读懂,线程,内存,多线程
From: https://blog.csdn.net/u012882823/article/details/139865255

相关文章

  • 等待执行完后一起收集的多线程
    多线程执行importorg.springframework.scheduling.annotation.Async;importorg.springframework.stereotype.Service;importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.CompletableFuture;importjava.util.concurrent.ExecutionExceptio......
  • JavaScript状态数据
    最近需要做一个三维场景切换的功能,切换场景后,还可以进行二三维模式的切换,二三维切换时,要定位到当前场景视角,那么场景的视角参数信息就需要保存到状态数据中,以供二三维场景切换时使用。项目是用vue做的,这里并没有使用vue的状态管理库,我是这样实现的:定义状态数据sceneInfolets......
  • 我一直看不明白:“C++会被java/python等这些语言替代”
    在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「C++的资料从专业入门到高级教程」,点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!!有些程序,是既可以用c++编写,也可以用java/python编写。如果这类程序以前主要是由c++编写,后来逐渐变成主要......
  • JavaScript的学习之旅之基本数据类型
    一、字面量(常量)和变量字面量:不可变的数据,一般位于等式的右边变量:可变的数据,位于等式的左边<script> //声明一个变量 //用关键字var声明 vara; //要为变量赋值 a=456 a=678 //声明和赋值可以同时进行 varb=34; console.log(b);</script>二、标识符......
  • JAVA SSE 服务端单向消息通知
    工作记录关于只需要服务端向web端单向通知的技术SSE的技术落地总结最近有个需求是关于消息的单向通知,原本考虑用websocket,但是技术经理认为太重,建议采用SSE.查阅相关技术后结合实际业务需要新建了一个工具类@Component@Slf4jpublicclassSSEUtils{privatefinalMap<......
  • 一个练习项目,好玩的bbs-java
    java这个我是用springboot做的目录结构   application.ymlspring:datasource:driver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://127.0.0.1:3306/my_bbs?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8&am......
  • Java语言设计
    第一章:Java环境搭建Java是一种计算机编程语言;除了java编程语言,还有很多的编程语言:c、c++、c#、python等不同编程语言类比于不同国家语言;每个编程语言的语法不同;应用场景不同Java是一个用于后端开发的编程语言 一、Java历史1.1995年,sun公司推出的一款面向对象的编程语......
  • Java语言设计
    第二章:变量、数据类型、运算符、表达式一、变量1.概念:计算机中的一块内存空间,存储数据的基本单元2.变量的组成部分:数据类型、变量名、数据3.语法:(1)先声明,再赋值:  数据类型变量名;//声明  变量名=值; //赋值   (2)声明的同时并赋值:  数......
  • Java语言设计3
    第三章:分支结构一、if分支结构1.基本if结构:(1)语法:  if(判断条件/布尔表达式){    //语句  }(2)执行原理:如果判断条件成立,则执行{}中的语句2.基本if结构2(1)语法:  if(判断条件/布尔表达式){    //语句1  }else{    //......
  • Java语言设计4
    第四章:循环结构一、理解:1.循环:通过某个条件,重复并且有规律的执行一段代码2.循环组成部分:循环变量的初始化、循环条件、循环变量的改变、循环体3.循环分类:while循环、do..while循环、for循环二、while循环1.语法://循环变量的初始化while(循环条件){  //循环......