Java的多线程以及内存模型的知识点梳理,有想到过这些吗?

JMM大致描述:

JMM描述了线程如何与内存进行交互。Java虚拟机规范视图定义一种Java内存模型,来屏蔽掉各种操作系统内存访问的差异,以实现Java程序在各种平台下都能达到一致的访问效果。

JMM描述了JVM如何与计算机的内存进行交互

JMM都是围绕着原子性,有序性和可见性进行展开的

JMM的主要目标是定义程序中各个变量的访问规则,虚拟机将变量存储到内存和从内存取出变量这样的底层细节。此处的变量指在堆中存储的元素。

多线程的时候为什么容易出错?

Java内存模型规定所有的共享变量都存储在主内存中,而每条线程有自己的工作内存(本地内存),工作内存保存了共享变量的副本,而不同内存又无法访问对方的工作内存,所以如果线程在工作内存中修改了变量副本,其它线程是无从得知的。

线程的传值均需要通过主内存来完成

主内存与工作内存如何交互?

Java内存模型定义了8种操作来完成主内存与工作内存的交互细节,虚拟机必须保证这8种操作的每一个操作都是原子的,不可再分的。

lock: 作用于主内存的变量,把变量标识为线程独占的状态

unlock: 与lock对应,把主内存中处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。

read: 作用于主内存的变量,把一个变量的值从主内存传输到线程的工作内存,便于随后的load使用。

load:作用于工作内存的变量,把read读取到的变量放入工作内存副本

use: 作用于工作内存,把工作内存的变量值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行这个操作。

assign: 作用于工作内存,把执行引擎收到的值赋给工作内存的变量,虚拟机遇到赋值字节码时候执行这个操作

store:作用于工作内存,把变量的值传输到住内存中,以便随后的write使用

write:作用于主内存,把store操作从工作内存得到的值放入主内存的变量中。

JMM内存模型

执行上述8种基本操作的规则:

不允许read和load,store和write操作之一单独出现。

不允许一个线程丢弃它最近的assign操作。即变量在工作内存中改变了账号必须把变化同步回主内存

一个新的变量只允许在主内存中诞生,不允许工作内存直接使用未初始化的变量。

一个变量同一时刻只允许一条线程进行lock操作,但同一线程可以lock多次,lock多次之后必须执行同样次数的unlock操作

如果对一个变量进行lock操作,那么将会清空工作内存中此变量的值。

不允许对未lock的变量进行unlock操作,也不允许unlock一个被其它线程lock的变量

如果一个变量执行unlock操作,必须先把次变了同步回主内存中。

这8种操作定义相当严禁,实践起来又比较麻烦,但是可以有助于我们理解多线程的工作原理。有一个与此8种操作相等的Happen-before原则。

Happen-before原则

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

天然的happen-before

程序顺序原则:一个线程内包装语义的串行性

volatile变量的写,先发生于读,这保证了volatile变量的可见性

锁规则:unlock先与lock

传递性:A 先于B,B先于C,那么A必然先于C

线程的start先于线程的每一个动作

线程的所有操作优先于线程的终结(Thread.join())

线程的中断(interupt)先于被中断线程的代码

对象的构造函数执行,先于finalize()方法

Java运行时数据区

JVM定义了一些程序运行时会使用到的运行时数据区,其中一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些是与现场一一对应的,这些线程对应的数据区会随着线程的开始和结束而创建和销毁。

这部分参考JVM规范

1. pc寄存器

可以支持多条线程同时允许,每一条Java虚拟机线程都有自己的pc寄存器。任意时刻,一条JVM线程之后执行一个方法的代码,这个方法被称为当前方法(current method)

如果这个方法不是native的,那么PC寄存器就保存JVM正在执行的字节码指令地址。

如果是native的,那么pc寄存器的值为undefined

pc寄存器的容量至少能保证一个returnAddress类型的数据或者一个平台无关的本地指针的值。

2. JVM Stack(虚拟机栈)

每一个JVM线程都有自己的私有虚拟机栈,这个栈与线程同时创建,用于存储栈帧(Frame)。

栈用来存储局部变量与一些过程结果的地方。在方法调用和返回中也扮演了很重要的角色。

栈可以试固定分配的也可以动态调整

如果请求线程分配的容量超过JVM栈允许的最大容量,抛出StackOverflowError异常

如果JVM栈可以动态扩展,扩展的动作也已经尝试过,但是没有申请到足够的内存,则抛出OutofMemoryError异常

3. Heap(堆)

堆是可以可供各个线程共享的运行时存储区域,也是供所有类的实例和数组对象分配内存的区域。堆在JVM启动的时候创建。

堆所存储的就是被GC所管理的各种对象。

堆也是可以固定大小和动态调整的:

实际所需的堆超过的GC所提供的最大容量,那么JVM抛出OutofMemoryError异常。

4. Method Area(方法区)

也是各个线程共享的运行时内存区,它存储每一个类的实例信息,运行时常量池,字段和方法数据,构造函数和普通方法的字节码等内容。还有一些特殊方法。

方法区是堆的逻辑组成部分,也在JVM启动时创建,简单的JVM可以不实现这个区域的垃圾收集。

方法区也可固定大小和动态分配与堆一样,内存空间不够,那么JVM抛出OutofMemoryError异常。

5. Run-Time Constant Pool(运行时常量池)

在方法区中分配,在加载类和接口到虚拟机之后,就创建对应的运行时常量池。

它是class文件中每一个类或接口的常量池表的运行时表现形式。像字符串。Java的主要类型。

存储区域不够用时候抛出OutofMemoryError异常。

6. Native Method Stacks(原生方法栈或本地方法栈)

JDK中native的方法,System类和Thread类中有很多。使用C语言编写的方法,这个也通常叫做C stack。

可以不支持本地方法栈,但是如果支持的时候,这个栈一般会在线程创建的时候按线程分配。

与栈的错误一样,StackOverFlowError和OutOfMemeoryError.

为了让学习变得轻松、高效,今天给大家免费分享一套Java入门教学资源。帮助大家在成为Java架构师的道路上披荆斩棘。需要入门的资料欢迎加入学习交流群:9285,05736

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/503305.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java性能优化方面的程序优化知识点归纳,希望对你有所帮助

常用的程序设计优化技巧: 1、字符串优化处理 (1)String 类的特点:不变性、针对常量池的优化( String.intern() 方法的意义) (2)subString 方法的内存泄漏 : (3&#…

java工具栏的工具提示,动态菜单项、状态条提示、工具条提示问题

问题的提出:一个应用程序想要动态改变菜单项。使用CCmdUI::SetText("Menu Text")可以改变菜单文本,但是如何动态改变工具条和状态条的文本呢?有几种策略,避免,欺骗,面对......首先,避…

python excel操作库,可能是全网最完整的 Python 操作 Excel库总结!

openpyxlxlrd/xlwtxlwingsxlsxwriter了解各个库的异同,从而在不同场景下可以灵活使用首先让我们来整体把握下不同库的特点“xlrdxlwtxlutils.xlsxlwt.xlsxlrd.xlsxlutilsxlrdxlwt.xlsxlrdxlwtxlutilsxlwingsXlsxWriter.xlsxopenpyxl.xlsxpandas”如果你懒得看详细的…

Java编程中程序员会遇到的一些感性烦恼,你有遇到吗?

如果作为兴趣来学编程,什么人都适合。毕竟,现在小学生都开始学习编程了。如果要作为职业来说,你到底适合不适合确实是个问题。我教过的学员里面从初中生到博士生、甚至50多岁的企业高管都有,怀着不同的目的来学习JAVA。 我记得教过…

java开发中spring常用的工具类

内置的resouce类型 UrlResourceClassPathResourceFileSystemResourceServletContextResourceInputStreamResourceByteArrayResourceEncodedResource 也就是Resource加上encoding, 可以认为是有编码的资源VfsResource(在jboss里经常用到, 相应还有 工具类 VfsUtils)org.springf…

python波士顿房价是什么数据,Python数据分析 | 波士顿房价回归分析

分析目标:将波士顿房价的数据集进行描述性数据分析、预测性数据分析(主要用了回归分析),可用于预测房价。数据集介绍:卡内基梅隆大学收集,StatLib库,1978年,涵盖了麻省波士顿的506个不同郊区的房屋数据。一…

Java开发的Spring Boot的核心模块

Spring Boot 的核心模块 下面我们大概来了解一下 Spring Boot 的核心模块。 1、spring-boot 这是 Spring Boot 的主模块,也是支持其他模块的核心模块,主要包含以下几点: 提供了一个启动 Spring 应用的主类,并提供了一个相当方便…

java开发中对于程序员的几点建议,你们有想到吗?

建议一:只有真正喜欢才能写好程序 喜欢写程序,做程序员就是上天堂; 不喜欢写程序,做程序员就是下地狱; 程序员需要整天趴在电脑前,经常没日没夜的,非常辛苦,而且工作来不得半点虚…

Java面向对象和面向过程有什么区别?网友:傻傻分不清楚……

面向对象,Obeject Oriented,是一种编程术语。面向对象是当今软件开发方法的主流方法之一,他是把数据以及对数据的操作放在一起,作为一个相互依存的整体,就是我们所说的对象。对同类对象抽象出其共性,就是类…

Java 反射机制和动态代理是基于什么原理,了解过吗?

工作多年以及在面试中,我经常能体会到,有些面试者确实是认真努力工作,但坦白说表现出的能力水平却不足以通过面试,通常是两方面原因: 1、“知其然不知其所以然”。 做了多年技术,开发了很多业务应用&#x…

成长为一名Java架构师需要掌握的技术有哪些呢?

Java架构师需要掌握的技术: 1、熟练使用各种框架,并知道它们实现的原理。 2、jvm虚拟机原理、调优,懂得jvm能让你写出性能更好的代码; 3、池技术,什么对象池,连接池,线程池……Java反射技术&…

Java程序员遇到瓶颈后我们可以试着朝四个方向拓展?你们觉得呢?

现如今随着IT行业的火热,人们对于编程技术也是越来越关注重视,在从业后我们做Java开发难免会遇到一些瓶颈。在我看来解决这个问题一般有以下4种方向: 基于产品本身 要记住公司招人是解决问题的,基于现有问题出发,大家…

oracle 布尔盲注,Oracle基于延时的盲注总结

0x00 前言oracle注入中可以通过页面响应的状态,这里指的是响应时间,通过这种方式判断SQL是否被执行的方式,便是时间盲注;oracle的时间盲注通常使用DBMS_PIPE.RECEIVE_MESSAGE(),而另外一种便是decode()与高耗时SQL操作…

Java架构师除了必备的技术之外,这些技能也需必备?你们觉得呢?

成为Java架构师首先你必须是一名Java高级开发工程师,熟练使用各种框架,并且能知道他们其中的原理。jvm虚拟机原理、调优,懂得jvm能让你写出性能更好的代码;池技术,什么对象池,连接池,线程池等等 Java构架师…

Java编程学习并不难,有坚持的动力与良好的心态尤为重要

时间过得很快,回想刚学习Java编程开发的懵懂无知,到现在可以做出简单的项目,可以明显的感觉到自己确实进步了。Java编程其实并不难学,难的是你能够一如既往的保持好的学习态度,并愿意努力的去背、去记、去做项目练习。…

Java编程开发中高效编码的7个技巧?你应该知道……

1. 使用 JDK 8 或更高版本 从 JDK 8 以及 更高版本开始,引进许多新功能将允许你编写更短、更具表现力的代码,包括 lambda 表达式、functional 接口、stream API等。你实际上不需要记住他们,因为 IDEA 将帮助你使用这些功能,这也是…

下载jdk一定要登录oracle么,如何下载oracle jdk|oracle jdk下载慢,要登录等等问题

/java/jdk/8u231-b11/5b13a193868b4bf28bcb45c792fce896/jdk-8u231-linux-x64.tar.gz注意替换--------------------------------------------附上一批网址,这些应该也够了http://ns1.iranns.ir 这个比较新https://mirrors.huaweicloud.com/java/http://enos.itcoll…

谈谈Java与大数据之间的关系你们都了解了清楚了吗?

Java是计算机编程语言界的王者,大数据是当下IT领域中最新潮的技术,Java和大数据都是当下十分受企业欢迎的IT技术,也是企业核心竞争力的重要组成部分,都说学大数据要先学Java,那么Java和大数据有什么关系呢?…

自学Java必看的知识点,猿们怎么看?

1.你需要精通面向对象分析与设计(OOA/OOD)、涉及模式(GOF,J2EEDP)以及综合模式。你应该了解UML,尤其是class、object、interaction以及statediagrams。 2. 你需要学习Java语言的基础知识以及它的核心类库(collections、serialization、streams、network…

谈一谈Java编程开发中虚拟机的内存区域划分?猿们怎么看?

java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,有的区域随虚拟机进程的启动而存在,有的区域则依赖线程而存在。包括以下几个运行时数据区域: 程序计数器(线程私有): 可以…