c++ 线程什么时候run_多线程并发支撑基础之JAVA内存模型

Java内存模型可以说是Java并发的底层支持,了解Java内存模型才能正在了解Java并发。

内存模型

在内存中设置一个变量"value = 1;"那么其他线程能在什么时候读取到这个结果呢?有可能不能立即甚至永远都读不到。比如指令顺序与源代码中的顺序不同;编译器会把变量保存在寄存器而不是内存中;处理器可以采用乱序或并行等方式来执行指令;缓存可能会改变将写入变量提交到主内存的次序,保存在处理器本地缓存中的值其他处理器是不可见的;这些情况都会导致其他线程不能读取到变量的最新值。

而Java内存模型(Java memory Model,简称JMM)则是规定了JVM在什么时候对变量的修改对其他线程可见

在多核处理器中,每个处理器都有自己的缓存,并且定期地与主内存进行协调,不同的处理器架构中提供了不同级别的缓存一致性。在现在的CPU中分了多级内存缓存比如寄存器、L1、L2、L3、内存等,每种处理器都有各自的规则和处理方式,而要保证修改变量对其他线程可见的难度就很大。

所以在JMM中抽象出来只分工作内存、主内存。主内存主要存共享变量,工作内存为每个线程拥有,存放线程需要的共享变量副本。各个线程只能读、改自己工作线程的数据,不能直接操作主内存的变量,线程修改变量时先修改工作内存变量再同步到主内存当中。

在多线程环境中,维护程序的串行性将会导致很大的性能开销,所以只有当多个线程要共享数据时,才必须协调它们之间的操作,并且JVM依赖程序通过同步操作来找出这些协调操作在何时发生。通过只分两种内存就简单很多了。

Happens-Before规则

上一节说到JVM通过依赖同步操作来找出协调操作在何时发生,而JMM就是通过各种操作来定义的。JMM对程序中的所有操作定义了一个偏序关系,称为Happens-Before

Happens-before简单解释下:如果第一个操作Happens-before第二个操作,也就是说第一个操作对于第二个操作时可见的,也就是第二个操作能够看到第一个操作的结果。

而Happens-before主要包含以下规则:

程序顺序规则:一个线程内肯定要保证执行顺序,比如两步代码前一步执行肯定要在下一步执行之前,如果不能保证规则那么如果后一步依赖前一步的结果那么肯定会出现错误。不过这个规则和指令重排冲突,但是执行重排是在保证执行结果依然符合Happens-before执行的结果下才重排,所以并不冲突。

监视器规则:对同一个锁,肯定前面一个释放了锁,后面一个才能获取到锁,只有获取到锁才能释放锁。

volatile变量规则:volatile修饰的变量在一个线程修改后,其他线程一定能够看到最新值。

线程启动规则:在主线程执行一个子线程,那么子线程的run方法一定能够看到主方法调用子线程的start方法之前的操作。

线程结束规则:主线程调用了子线程的start后如果再调用join方法,那么join方法肯定能看到子线程run方法执行的结果。

中断规则:对线程执行Interrupt方法后,那么执行interrupted和isInterrupted都能看到结果。

终结器规则:对象的构造函数必须在对象的终结器执行前完成。

传递性:A操作在B之前,B在C之前,那么A一定在C之前,也就是C一定能够看到A执行的结果。

在多线程中每个线程每段代码执行的时间是不确定的,而Happens-before则保证了单个线程内执行顺序,同时也保证在多线程哪些情况下有先后顺序。比如比如在线程A中执行了线程B的start方法和B线程的join方法,那么B线程的run方法肯定在A在调用B的start方法之后执行,也就是B中的run方法能看到之前的执行结果。同样join方法一定是run方法结束以后才能执行,也就是join之后的程序能够看到run执行的结果。

单例模式的双重检查

单例模式的一种实现方式代码如下图:

0eedb57347b20ef74823f73038f5f822.png

volatile保证了变量的可见性,就是前面讲到的volatile变量规则,在第二次验证变量singleton时才能得到的正确。如果变量没有用volatile修饰一个线程初始化了,初始化结果可能还在工作内存中,即使同步到主内存中,但是如果没有同步到其他内存中,那么其他线程就可能再次初始化。

总结

JMM实际上是由定义的一系列操作组成,这些操作确定了Java的基础特性,尤其在多线程并发方面,它主要对重排序、原子性、内存可见性这三个方面维护保证了多线程的正确执行。

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!

f98b84ebacb900e5abdececfcd2fecaf.png

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

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

相关文章

润乾报表 数据集ds1中,数据源xmglxt_x3无数据库连接,且未设定数据连接工厂,请检查数据源设定:...

一、润乾报表错误内容 产生数据工厂: com.runqian.report4.dataset.SQLDataSetFactory 失败 错误来源:: 数据集ds1中,数据源xmglxt_x3无数据库连接,且未设定数据连接工厂,请检查数据源设定: 二、解决方法 同事做的润乾…

WPF中的数据绑定Data Binding使用小结

完整的数据绑定的语法说明可以在这里查看: http://www.nbdtech.com/Free/WpfBinding.pdf MSDN资料: Data Binding: Part 1 http://msdn.microsoft.com/en-us/library/aa480224.aspx Data Binding: Part 2 http://msdn.microsoft.com/en-us/library/aa480…

Swift 将日期转化为字符串,显示上午还是下午

let dateF DateFormatter() // aaa 用于显示上午还是下午,mm和MM 分别表示12小时制和24小时制 dateF.dateFormat "yyyy-MM-dd aaa hh:mm:ss" dateF.amSymbol "上午" dateF.pmSymbol "下午" let str dateF.string(from: Date()) …

车间生产能耗管控方案_如何给生产车间降温 环保空调的这些方案一定能帮到你...

生产车间闷热如何降温?高温闷热带来的影响是非常大,在厂房车间闷热的环境会影响作业人员的情绪,增加燥热感,使工作效率下降,生产力降低,产品质量变差,蕞严重的结果导致客户流失,所以…

app开发人脸登录和指纹登录_易讯云通讯推出“一键登录”,为App登录提供新方案...

移动互联网时代,用户的耐心越来越少,注意力也越来越弱,追求便捷与高效。登录的方式从自定义的账号密码登录,到邮箱登录,到第三方登录与手机验证码登录两种登录方式进行竞争,到现在的个人指纹,人…

可以直接考甲级吗_成人高考可以考本科吗?成人高考可以考研究生吗?

成人高考可以考本科吗?成人高考可以考研究生吗?当你选择利用成人高考的方式来提升学历的时候,那么我们需要了解关于成人高考的知识越多越好。成人高考可以考本科吗?成人高考可以考研究生吗?相信这是很多考生都想要了解的问题。成人高考可以考本科吗?成人高考可…

python变量和字符串

这段时间忘记更博了,学的太投入就一口气把python都学完,做了几个上手的小项目,自娱自乐,把笔记都写在百度云笔记中,现在就开始把所有笔记都粘贴复制分享给大家把 变量变量就是编程最基本的存储单位比如a12,…

Python中曲率与弯曲的转换_黎曼几何学习笔记(3)——共形数量曲率与高斯曲率...

参考文献:(GTM171)Peter《Riemannian Geometry》,Richard Mikula《Notes on the Yamabe Flow》,夏青《曲面上的预定高斯曲率问题》.我声明以下内容我亲自验算过,在文章后面我会给出我的部分验算手稿.设是维紧致可定向黎曼流形&…

Nginx服务基础

Nginx的英文官方网站是http://nginx.org,在这里可以查看Nginx的各个软件版本信息。Nginx软件有三种版本:稳定版、开发版和历史稳定版。开发版更新较快,包含最新的功能和bug的修复,但同时也可能会遇到新的bug,开发版的更…

yum如何安装特定版本的gcc_linux下如何升级python

Python 的概念小编使用的centos7下的python版本为2.7,而python要全面转向python3,故升级pyhton迫在眉睫,今天来介绍一下如何升级centos下的python首先要确定需要升级的python3的版本,比如小编想升级到3.7.0,在linux下输入命令:这条…

java报错空指针异常_夯实基础:认识一下这10 个深恶痛绝的 Java 异常

异常是 Java 程序中经常遇到的问题,我想每一个 Java 程序员都讨厌异常,一 个异常就是一个 BUG,就要花很多时间来定位异常问题。什么是异常及异常的分类请看这篇文章:异常小结:上一张图搞清楚Java的异常机制。今天来列一…

页面分页

需求:当数据很多,一个页面难以展现时,便需要分页来实现。 说在前面: 1.每一页展示的数据可以从数据库中抽取出来,数据查询方法中有limit这个方法,limit x,y —–>x表示从第几条数据开始查询,…

typora打开pdf文件提示文件过大_Win7/Win10拷贝到U盘容量足够却提示文件过大的解决方法...

前段时间,装机之家分享了系统安装的教程,不过有用户在拷贝系统镜像文件的时候,出现了系统提示文件过大,但是U盘容量足够大,这是什么情况呢?下面装机之家分享的Win7/Win10系统下拷贝到U盘容量足够却提示文件…

图像卷积与滤波的一些知识点

http://blog.csdn.net/zouxy09/article/details/49080029 之前在学习CNN的时候,有对卷积进行一些学习和整理,后来就烂尾了,现在稍微整理下,先放上来,以提醒和交流。 一、线性滤波与卷积的基本概念 线性滤波可以说是图像…

1到10选一个数字读心术_厉害了!quot;广东110“互联网报警满足您多场景报警需求!...

01报警人哎,110,这边打架了。(南方口音)警察在哪里?报警人在fa ben 市场门口嘛。警察什么“发奔”市场,没听过这个地方,你能讲清楚点吗?报警人就是那个卖“发发”草草的市场嘛,哎,这都不知道,…

学生免费用IDEA

第一步:官网免费申请 进去之后点击立即申请。 来到这个界面: 这时候有些博主就瞎写了,搞的我弄半天电子邮件。 其实在校大学生应该点击官方文件 按照要求填写就行了,自己的邮箱,学信网的证明,学校名称等…

网页设计如何排成一列_网页设计如何影响以及改善SEO?

在当今的SEO世界中,网站设计实践也起着关键作用。用户体验已成为搜索引擎排名的关键因素。因此,您网站的设计以及用户与网站的交互方式会直接影响您网站在搜索结果中的排名。在本文中,我们将重点介绍一些可能对网站的SEO性能有直接影响的网站…

Tensorflow模型加载与保存、Tensorboard简单使用

先上代码: from __future__ import absolute_import from __future__ import division from __future__ import print_function # -*- coding: utf-8 -*- """ Created on Tue Nov 14 20:34:00 2017author: HJL """# Copyright 2015 T…

cesium添加填充_Cesium中级教程1 - 空间数据可视化(一)

Cesium中文网:http://cesiumcn.org/| 国内快速访问:http://cesium.coinidea.com/本教程将教读者如何使用Cesium的实体(Entity)API绘制空间数据,如点、标记、标签、线、模型、形状和物体。不需要Cesium的先验知识&#…

atomic原子类实现机制_并发编程:并发操作原子类Atomic以及CAS的ABA问题

本文基于JDK1.8Atomic原子类原子类是具有原子操作特征的类。原子类存在于java.util.concurrent.atmic包下。根据操作的数据类型,原子类可以分为以下几类。基本类型AtomicInteger:整型原子类AtomicLong:长整型原子类AtomicBoolean:…