java基础之 内存模型

JVM内存模型 Java内存模型 Java内存模型是共享内存的并发模型,线程之间主要通过读-写共享变量(堆内存中的实例域,静态域和数组元素)来完成隐式通信。 Java 内存模型(JMM)控制 Java 线程之间的通信,决定一个线程对共享变量的写入何时对另一个线程可见。 计算机高速缓存和缓存一致性 计算机在高速的 CPU 和相对低速的存储设备之间使用高速缓存,作为内存和处理器之间的缓... 阅读详情


 Java运行时数据区分为下面几个内存区域

1.PC寄存器/程序计数器:

  严格来说是一个数据结构,用于保存当前正在执行的程序的内存地址,由于Java是支持多线程执行的,所以程序执行的轨迹不可能一直都是线性执行。当有多个线程交叉执行时,被中断的线程的程序当前执行到哪条内存地址必然要保存下来,以便用于被中断的线程恢复执行时再按照被中断时的指令地址继续执行下去。为了线程切换后能恢复到正确的执行位置,每个线程都需要有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存,这在某种程度上有点类似于“ThreadLocal”,是线程安全的。

2.Java栈 Java Stack:

  Java栈总是与线程关联在一起的,每当创建一个线程,JVM就会为该线程创建对应的Java栈,在这个Java栈中又会包含多个栈帧(Stack Frame),这些栈帧是与每个方法关联起来的,每运行一个方法就创建一个栈帧,每个栈帧会含有一些局部变量、操作栈和方法返回值等信息。每当一个方法执行完成时,该栈帧就会弹出栈帧的元素作为这个方法的返回值,并且清除这个栈帧,Java栈的栈顶的栈帧就是当前正在执行的活动栈,也就是当前正在执行的方法,PC寄存器也会指向该地址。只有这个活动的栈帧的本地变量可以被操作栈使用,当在这个栈帧中调用另外一个方法时,与之对应的一个新的栈帧被创建,这个新创建的栈帧被放到Java栈的栈顶,变为当前的活动栈。同样现在只有这个栈的本地变量才能被使用,当这个栈帧中所有指令都完成时,这个栈帧被移除Java栈,刚才的那个栈帧变为活动栈帧,前面栈帧的返回值变为这个栈帧的操作栈的一个操作数。


3.堆 Heap:

  堆是JVM所管理的内存中国最大的一块,是被所有Java线程锁共享的,不是线程安全的,在JVM启动时创建。堆是存储Java对象的地方,这一点Java虚拟机规范中描述是:所有的对象实例以及数组都要在堆上分配。Java堆是GC管理的主要区域,从内存回收的角度来看,由于现在GC基本都采用分代收集算法,所以Java堆还可以细分为:新生代和老年代;新生代再细致一点有Eden空间、From Survivor空间、To Survivor空间等。

4.方法区Method Area:

  方法区存放了要加载的类的信息(名称、修饰符等)、类中的静态常量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当在程序中通过Class对象的getName.isInterface等方法来获取信息时,这些数据都来源于方法区。方法区是被Java线程锁共享的,不像Java堆中其他部分一样会频繁被GC回收,它存储的信息相对比较稳定,在一定条件下会被GC,当方法区要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。方法区也是堆中的一部分,就是我们通常所说的Java堆中的永久区 Permanet Generation,大小可以通过参数来设置,可以通过-XX:PermSize指定初始值,-XX:MaxPermSize指定最大值。

5.常量池Constant Pool:

  常量池本身是方法区中的一个数据结构。常量池中存储了如字符串、final变量值、类名和方法名常量。常量池在编译期间就被确定,并保存在已编译的.class文件中。一般分为两类:字面量和应用量。字面量就是字符串、final变量等。类名和方法名属于引用量。引用量最常见的是在调用方法的时候,根据方法名找到方法的引用,并以此定为到函数体进行函数代码的执行。引用量包含:类和接口的权限定名、字段的名称和描述符,方法的名称和描述符。

6.本地方法栈Native Method Stack:

  本地方法栈和Java栈所发挥的作用非常相似,区别不过是Java栈为JVM执行Java方法服务,而本地方法栈为JVM执行Native方法服务。本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。

  

主内存和工作内存:

  Java内存模型的主要目标是定义程序中各个变量的访问规则,即在JVM中将变量存储到内存和从内存中取出变量这样的底层细节。此处的变量与Java编程里面的变量有所不同步,它包含了实例字段、静态字段和构成数组对象的元素,但不包含局部变量和方法参数,因为后者是线程私有的,不会共享,当然不存在数据竞争问题(如果局部变量是一个reference引用类型,它引用的对象在Java堆中可被各个线程共享,但是reference引用本身在Java栈的局部变量表中,是线程私有的)。为了获得较高的执行效能,Java内存模型并没有限制执行引起使用处理器的特定寄存器或者缓存来和主内存进行交互,也没有限制即时编译器进行调整代码执行顺序这类优化措施。

  JMM规定了所有的变量都存储在主内存(Main Memory)中。每个线程还有自己的工作内存(Working Memory),线程的工作内存中保存了该线程使用到的变量的主内存的副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量(volatile变量仍然有工作内存的拷贝,但是由于它特殊的操作顺序性规定,所以看起来如同直接在主内存中读写访问一般)。不同的线程之间也无法直接访问对方工作内存中的变量,线程之间值的传递都需要通过主内存来完成。


  由于Java栈是与线程对应起来的,Java栈数据不是线程共有的,所以不需要关心其数据一致性,也不会存在同步锁的问题。

  在Java虚拟机规范中,对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。在Hot Spot虚拟机中,可以使用-Xss参数来设置栈的大小。栈的大小直接决定了函数调用的可达深度。


线程1和线程2要想进行数据的交换一般要经历下面的步骤:

  1.线程1把工作内存1中的更新过的共享变量刷新到主内存中去。

  2.线程2到主内存中去读取线程1刷新过的共享变量,然后copy一份到工作内存2中去。

 

 Java内存模型是围绕着并发编程中原子性、可见性、有序性这三个特征来建立的,那我们依次看一下这三个特征

原子性(Atomicity):一个操作不能被打断,要么全部执行完毕,要么不执行。在这点上有点类似于事务操作,要么全部执行成功,要么回退到执行该操作之前的状态。

  基本类型数据的访问大都是原子操作,long 和double类型的变量是64位,但是在32位JVM中,32位的JVM会将64位数据的读写操作分为2次32位的读写操作来进行,这就导致了long、double类型的变量在32位虚拟机中是非原子操作,数据有可能会被破坏,也就意味着多个线程在并发访问的时候是线程非安全的。

下面我们来演示这个32位JVM下,对64位long类型的数据的访问的问题:



因为在32位JVM中,64位的long数据的读和写都不是原子操作,即不具有原子性,并发的时候相互干扰了


可见性:一个线程对共享变量做了修改之后,其他的线程立即能够看到(感知到)该变量这种修改(变化)。

  Java内存模型是通过将在工作内存中的变量修改后的值同步到主内存,在读取变量前从主内存刷新最新值到工作内存中,这种依赖主内存的方式来实现可见性的。

无论是普通变量还是volatile变量都是如此,区别在于:volatile的特殊规则保证了volatile变量值修改后的新值立刻同步到主内存,每次使用volatile变量前立即从主内存中刷新,因此volatile保证了多线程之间的操作变量的可见性,而普通变量则不能保证这一点。

  除了volatile关键字能实现可见性之外,还有synchronized,Lock,final也是可以的。

  使用synchronized关键字,在同步方法/同步块开始时(Monitor Enter),使用共享变量时会从主内存中刷新变量值到工作内存中(即从主内存中读取最新值到线程私有的工作内存中),在同步方法/同步块结束时(Monitor Exit),会将工作内存中的变量值同步到主内存中去(即将线程私有的工作内存中的值写入到主内存进行同步)。

  使用Lock接口的最常用的实现ReentrantLock(重入锁)来实现可见性:当我们在方法的开始位置执行lock.lock()方法,这和synchronized开始位置(Monitor Enter)有相同的语义,即使用共享变量时会从主内存中刷新变量值到工作内存中(即从主内存中读取最新值到线程私有的工作内存中),在方法的最后finally块里执行lock.unlock()方法,和synchronized结束位置(Monitor Exit)有相同的语义,即会将工作内存中的变量值同步到主内存中去(即将线程私有的工作内存中的值写入到主内存进行同步)。

  final关键字的可见性是指:被final修饰的变量,在构造函数数一旦初始化完成,并且在构造函数中并没有把“this”的引用传递出去(“this”引用逃逸是很危险的,其他的线程很可能通过该引用访问到只“初始化一半”的对象),那么其他线程就可以看到final变量的值。

  有序性:对于一个线程的代码而言,我们总是以为代码的执行是从前往后的,依次执行的。这么说不能说完全不对,在单线程程序里,确实会这样执行;但是在多线程并发时,程序的执行就有可能出现乱序。用一句话可以总结为:在本线程内观察,操作都是有序的;如果在一个线程中观察另外一个线程,所有的操作都是无序的。前半句是指“线程内表现为串行语义(WithIn Thread As-if-Serial Semantics)”,后半句是指“指令重排”现象和“工作内存和主内存同步延迟”现象。

Java提供了两个关键字volatile和synchronized来保证多线程之间操作的有序性,volatile关键字本身通过加入内存屏障来禁止指令的重排序,而synchronized关键字通过一个变量在同一时间只允许有一个线程对其进行加锁的规则来实现,

在单线程程序中,不会发生“指令重排”和“工作内存和主内存同步延迟”现象,只在多线程程序中出现。

 

happens-before原则:

  Java内存模型中定义的两项操作之间的次序关系,如果说操作A先行发生于操作B,操作A产生的影响能被操作B观察到,“影响”包含了修改了内存中共享变量的值、发送了消息、调用了方法等。

  下面是Java内存模型下一些”天然的“happens-before关系,这些happens-before关系无须任何同步器协助就已经存在,可以在编码中直接使用。如果两个操作之间的关系不在此列,并且无法从下列规则推导出来的话,它们就没有顺序性保障,虚拟机可以对它们进行随意地重排序。

  a.程序次序规则(Pragram Order Rule):在一个线程内,按照程序代码顺序,书写在前面的操作先行发生于书写在后面的操作。准确地说应该是控制流顺序而不是程序代码顺序,因为要考虑分支、循环结构。

  b.管程锁定规则(Monitor Lock Rule):一个unlock操作先行发生于后面对同一个锁的lock操作。这里必须强调的是同一个锁,而”后面“是指时间上的先后顺序。

  c.volatile变量规则(Volatile Variable Rule):对一个volatile变量的写操作先行发生于后面对这个变量的读取操作,这里的”后面“同样指时间上的先后顺序。

  d.线程启动规则(Thread Start Rule):Thread对象的start()方法先行发生于此线程的每一个动作。

  e.线程终于规则(Thread Termination Rule):线程中的所有操作都先行发生于对此线程的终止检测,我们可以通过Thread.join()方法结束,Thread.isAlive()的返回值等作段检测到线程已经终止执行。

  f.线程中断规则(Thread Interruption Rule):对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测是否有中断发生。

  g.对象终结规则(Finalizer Rule):一个对象初始化完成(构造方法执行完成)先行发生于它的finalize()方法的开始。

  g.传递性(Transitivity):如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。

  一个操作”时间上的先发生“不代表这个操作会是”先行发生“,那如果一个操作”先行发生“是否就能推导出这个操作必定是”时间上的先发生 “呢?也是不成立的,一个典型的例子就是指令重排序。所以时间上的先后顺序与happens-before原则之间基本没有什么关系,所以衡量并发安全问题一切必须以happens-before 原则为准。

 



【报错】open /var/lib/docker/tmp/docker-import-863402796/bin/json: no such file or directory 然后,通过docker images可以看到镜像已经加载进来了。然后,通过docker images可以看到镜像已经加载进来了。 阅读详情

相关推荐

【汽车主动降噪】【ANC算法优化】基于深度学习的汽车主动噪声控制技术研究及Matlab实现

本文探讨了基于深度学习的汽车主动降噪(ANC)算法优化方案。针对传统FXLMS算法在应对复杂、非线性车内噪声时的局限性,文章详细解析了如何利用神经网络作为非线性建模器、深度滤波器或智能步长调节器来增强ANC系统性能,并提供了完整的Matlab仿真实战流程,展示了深度学习在提升降噪效果和收敛速度方面的潜力。

seed的博客 540

并发编程(三) - 重排序,happens-before原则,顺序一致性

重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。 上一篇文章中已经介绍了从Java源代码到最终实际执行的指令序列,会分别经历下面3种重排序: 1属于编译器重排序,2和3属于处理器重排序。 这些重排序可能会导致多线程程序出现内存可见性问题。在单线程程序中,对存在控制依赖的操作重排序,不会改变执行结果(这也是as-if-serial语义允许对存在控制依赖的操作做重排序的原因);但在多线程程序中,对存在控制依赖的操作重排序,可能会改变程序的执行结果。 1.数据依...

ForestCat的专栏 1279

RAG 赋能客服机器人:多轮对话与精准回复

在人工智能技术飞速发展的今天,客服机器人已成为企业提升服务效率的重要工具。然而,传统客服系统在多轮对话连贯性和精准回复能力上存在明显短板。检索增强生成(Retrieval-Augmented Generation, RAG)技术通过结合大语言模型(LLM)与外部知识库,为解决这一问题提供了创新路径。本文将深入探讨 RAG 在客服机器人中的应用,重点分析其如何实现多轮对话与精准回复,并结合实际案例与技术框架展开讨论。

shuizhudan223的博客 2142

Java内存模型(Memory Model)

    Java内存模型,Java Memory Model,我个人更喜欢“Java存储模型”的译法。  介绍  如前所述,JVM被设计成一台抽象的虚拟计算机,JVM的并发问题及解决方案与物理计算机中的并发问题有很多相似之处。  由于现代计算机的内存与CPU在运算速度上的巨大差别,通常会加入一层更接近CPU读写速度的高速缓存(Cache),将运算使用到的数据复制到Cache中,让运算能加速进行,运...

weixin_34015566的博客 268

“挑战杯”大赛“揭榜挂帅”赛道-baseline解析

在这个脚本中,txt文件的保存路径为'yolov7/datasets/Fatigue_driving_detection/txt_labels/',而xml文件的路径为'./label_xml/'。标注图片后的产物是会给每一个图片对应生成一个xml格式的文件,但是如果要用yolo框架去训练模型,输入的数据必须是txt格式,因此这里有一步转换格式的过程。注意看:obs这里有三个文件夹,第一个是关键帧的文件夹A,第二个是标注时输出的位置为文件夹B,第三个是智能标注后和手动标注的合集文件夹C。

m0_62899814的博客 2321

数据分析案例-2024年裁员数据集可视化分析

本实验数据集来源于Kaggle,原始数据集为2020-2024年裁员数据,共有3577条,12个变量,该数据集提供了不同公司的裁员信息。它包括以下几栏:Company:裁员发生的公司名称。Location_HQ:公司总部位置。Industry:公司所属的行业或部门。Laid_Off_Count:公司解雇的员工数量。Percentage:公司员工被解雇的百分比。Date:裁员发生的日期。Source:信息来源网址。Funds_Raised:公司募集资金的信息。

m0_64336780的博客 1万+

JMM-线程模型

JMM 缓存行

csywxr的博客 278

2025小红书爬虫还能活?破解x-s签名+动态Cookie,亲测爬1000条笔记零封禁(附逆向全过程)

上周帮美妆行业的朋友爬小红书“口红推荐”笔记,刚发30个请求就被403,抓包一看x-s签名不对;换Cookie继续爬,爬50条又被封——小红书的反爬这两年简直是“地狱模式”:动态Cookie每10分钟过期,x-s签名算法季度更新,连请求头的User-Agent顺序错了都会被拦。。这篇文章不藏私,把逆向x-s签名的全过程、动态Cookie的维护技巧、1000条稳定爬取的实战代码全给你,连我踩过的8个坑都标出来了(最后附代理池配置,IP零封禁的关键)。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 7404

并发编程---JMM模型

引言 在了解本文之前,我们知道所谓的并发编程就是平日中接触的多线程编程,既然扯到了多线程,那一定绕不开多线程的一些特性以及每个线程的结构或者说是线程的内存模型。接下来,我们从JMM(Java线程内存模型)来进行一些原理上的剖析。 多线程的关系分为三种: 1.同步:线程之间的协作 2.互斥:常见的互斥锁 3.分工:大任务的拆解 多线程经常遇到的问题: 1.死锁 2.资源共享问题 3.CPU调度问题(线程是由CPU来调度,JVM是没有权限的) 4.脏读 5.原子性问题 并发的特性是什么?本质又是解决

qq_36368893的博客 1042

龙虾机器人(OpenClaw)本地部署完全技术指南

在开始部署之前,我们需要明确部署的对象。通常所说的“龙虾机器人”指的是开源项目 OpenClaw(曾用名:Clawdbot、Moltbot)。它由程序员彼得·斯坦伯格开发,是一个开源的、可本地部署的通用型AI代理系统。与ChatGPT等对话式AI不同,OpenClaw被赋予了操作系统的权限:它可以执行终端命令、读写文件、操控浏览器、安装软件,甚至通过MCP协议调用外部工具。

huanghm88的专栏 2万+

RK3568平台开发系列讲解(项目篇)手写数字识别

📢 本篇章带大家基于飞桨(PaddlePaddle),完成一个简单的手写数字识别任务。

内核笔记 1182

Java内存模型基础

​简介: Java线程之间的通信对程序员完全透明,内存可见性问题很容易困扰Java程序员,这一系列几篇文章将揭开Java内存模型的神秘面纱。这一系列的文章大致分4个部分,分别是: Java内存模型基础,主要介绍内存模型相关基本概念 Java内存模型中的顺序一致性,主要介绍重排序与顺序一致性内存模型 同步原语,主要介绍三个同步原语(synchronized、volatile和final)的内存语义及重排序规则在处理器中的实现 Java内存模型的设计,主要介绍Java内存模型的设计原理,及其与处理器内存模型和

Java框架、并发编程、分布式、微服务、Redis、HarmonyOS、中间件等技术 563

SPMI协议学习总结

SPMI(System Power Management Interface)是由MIPI(Mobile Industry Processor Interface)联盟定义的一种硬件接口标准,它主要用于移动设备中,连接SoC(System on Chip)处理器系统的集成电源控制器与一个或多个电源管理IC(PMIC),以实现精确的电源管理

歌颂苦难的行为是无耻的; 1079

java内存模型基础

java内存模型基础油

qq_41820066的博客 162

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

关于 java:8. Java 内存模型与 JVM 基础

类加载器负责加载类的字节码,并生成 Class 对象。JVM 中类由类加载器标识,类名 + 加载器才能唯一确定一个类。所以:两个类名相同但由不同 ClassLoader 加载,它们是两个不同的类。@Override// 你自定义的加载逻辑可用于加密类解密、插件隔离、JVM内存马注入等。

Triste__chengxi的博客 4446

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

JVM第七讲:JVM 基础 - Java 内存模型详解

本文是JVM第七讲,JVM 基础 - Java 内存模型详解。主要转载自 Info 上[深入理解Java内存模型](https://www.infoq.cn/article/java_memory_model/), 作者程晓明。这篇文章对JMM讲的很清楚了,大致分三部分:1、重排序与顺序一致性;2、三个同步原语(lock,volatile,final)的内存语义,重排序规则及在处理器中的实现;3、java 内存模型的设计,及其与处理器内存模型和顺序一致性内存模型的关系。

Jet_qi的博客 489

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java内存模型基础篇

我们在这里简单复习一下操作系统中的缓存 操作系统中的缓存情况为上图,操作系统将内存,缓存分为多个大小相等的块。然后根据缓存的数目依次指定内存块所对应的缓存块,在使用时,直接访问缓存,未命中则更新。 但是操作系统的缓存有一个很关键的隐含信息:每个内存块只有一个缓存,一个缓存对应了多个内存。 但是在Java内存模型中,情况却似乎反了过来,如下图 Java内存模型 在Java中, 实例域、静态域和数组元素都存储在堆内存中,堆内存在线程之间共享(也就是共享变量 局部变量,方法定义参数,异常处理参数不会在线

可乐的博客 374

Java内存模型的基础

前言 在讲volatile之前先看一个例子 Processor A Processor B 代码 a=1;//A1 x=b;//A2 b=2;//B1 y=a;//B2 假设处理器A和处理器B按顺序并行执行内存访问,最终可能得到x=y=0的结果。 首先,大家可能都知道对于线程A与线程B而言,各自的处理器都只能看到自己缓冲区里面的数据,要想看到其他线程的数据,必须在主内...

ali_lili的博客 131

程序员:一篇文章弄懂Java多线程基础和Java内存模型

做为一个java程序员,多线程开发是避免不了的,多线程是基础技术,但同时也是一个比较重要、比较难的知识点。 今天通过这篇文章带大家了解一下java多线程的基础知识和Java内存模型。 转发+关注,然后私信回复 “乐字节” 免费领取更多Java干货 Java多线程生命周期,首先看下面这张经典的图,图中基本上囊括了Java中多线程重要知识点。 Java线程具有五种基本状态 1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态; 2.同步阻塞 – 线程在获取synch

HUIYL111的博客 295

十分钟看Java基础:Java内存模型

文章目录一、 Java内存模型的基础1. 总述2. 简介二、 进一步了解Java内存模型(一)重排序(为了优化、提升性能)(二)顺序一致性内存模型三、 关键词的内存语义(一)volatile(二) 锁写在最后 说明:本文的大部分内容参考和摘取了《Java并发编程艺术》这本书,对我来说也相当于做笔记吧。 一、 Java内存模型的基础 1. 总述 内存模型,我简单的理解就是Java在运行过程中的JVM对内存进行一系列操作的框架或者了流程(仅代表个人观点)。 在并发编程中,主要需要处理两个关键的问题:线程之间的通

教我数理化的博客 315

4.Java内存模型基础

文章目录@[toc]Java内存模型的基础1. 并发编程模型的两个关键问题2. Java内存模型的抽象结构3. 从源代码到指令序列的重排序4. 并发编程模型的分类5. happens-before简介 Java内存模型的基础 1. 并发编程模型的两个关键问题 两个问题: 线程之间如何通信 线程之间如何同步 通信:线程之间以何种机制来交换信息 同步:程序组用于控制不同线程间操作发生相对顺序的机制 两种并发模型: 共享内存:线程之间共享程序的公共状态,通过写-读内存中的公共状态来隐式通信,同步是显式进行的

Loritas的小窝~ 279

深入理解Java内存模型(一)——基础

深入理解Java内存模型(一)——基础 http://ifeve.com/java-memory-model-1/

vsddvsd的专栏 358

三、Java内存模型---Java内存模型的基础

3.1 Java内存模型的基础 3.1.1 并发编程模型的两个关键问题 并发编程中,有两大关键问题:线程之间如何通信和线程之间如何同步。通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递。 在共享内存的并发模型里,线程之间共享程序的公共状态,通过写-读内存中的公共状态 进行隐式通信。 在消息传递的并发模型里,线程之间没有公共状态,线程之间必须

岁月无痕的博客 563

6 Java内存模型基础知识

6 Java内存模型基础知识 6.1 并发编程模型的两个关键问题 线程间如何通信?即:线程之间以何种机制来交换信息 线程间如何同步?即:线程以何种机制来控制不同线程间操作发生的相对顺序 有两种并发模型可以解决这两个问题: 消息传递并发模型 共享内存并发模型 这两种模型之间的区别如下表所示: image 在Java中,使用的是共享内存并发模型。 6.2 Java内存模型的抽象结构 6.2...

陈陈陈亚萌_的博客 153

java 内存模型基础总结

Java内存模型:如图1 线程通信:如图2 重排序:程序效率 happens-before:满足即不会重排序 内存屏障指令:禁止重排序的实现 数据依赖性:单个线程存在即不会重排 as-if-serial:保证重排对单个线程的结果无影响 数据竞争:正确同步则没有竞争且具有顺序一致性 顺序一致性:保证可见性和一致性 同步:包括对常用同步原语(lock,volatile和final)的正

Code-lover's Learning Notes 1467

【Java基础】Java内存模型总结

Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信。多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变量来实现 同步是显式进行的。程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行。 1、多线程通信 1.1 内存模型 Java线程之间的通信由Java内存模型(JMM)控制,

youxia0075454的专栏 611
上一篇: Java基础之 语法糖
下一篇: linux 网卡丢失无法启动问题 解决方法
codeeee
博客等级 码龄12年 0粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值