Java并发编程——volatile

1. 并发编程的两个关键问题

并发是让多个线程同时履行,若线程之间是独立的,那并发实现起来很简单,各自履行各自的就行;但常常多条线程之间需要同享数据,此时在并发编程进程中就不可避免要斟酌两个问题:通讯 与 同步。

  • 通讯 
    通讯是指消息在两条线程之间传递。 
    既然要传递消息,那接收线程 和 发送线程之间必须要有个前后关系,此时就需要用到同步。通讯和同步是相辅相成的。

  • 同步 
    同步是指,控制多条线程之间的履行次序。

2. 通讯的方式

2.1 通讯方式的种类

线程之间的通讯1共有两种方式:同享内存 和 消息传递。

  • 同享内存 
    同享内存指的是多条线程同享同1片内存,发送者将消息写入内存,接收者从内存中读取消息,从而实现了消息的传递。 
    但这类方式有个弊端,即需要程序员来控制线程的同步,即线程的履行次序。

这类方式并没有真正地实现消息传递,只是从结果上来看就像是将消息从1条线程传递到了另外一条线程。

  • 消息传递 
    顾名思义,消息传递指的是发送线程直接将消息传递给接收线程。 
    由于履行次序由并发机制完成,因此不需要程序员添加额外的同步机制,但需要声明消息发送和接收的代码。

综上所述:对同享内存的通讯方式,需要进行显示的同步,隐式的通讯; 
而对消息传递的通讯方式,需要隐式的同步,显示的通讯。

2.2 Java使用的通讯方式

Java使用同享内存的方式实现多线程之间的消息传递。因此,程序员需要写额外的代码用于线程之间的同步。

PS:其实同享内存的方式从实现进程来看,跟消息传递1点关系都没有:1条线程将消息存入同享内存,另外一条线程从同享内存中读这条消息。 
但从结果来看,全部进程就好像是1条消息被从线程A传递到了线程B。 
这类方式之所以能实现消息传递,依托于两点:

  • 必须有1片同享的内存
  • 必须要实现多线程的同步

3. Java多线程的内存模型(简化版)

所有线程都同享1片内存,用于存储同享变量; 
另外,每条线程都有各自的存储空间,存储各自的局部变量、方法参数、异常对象。

4. volatile是甚么?

Java采取同享内存的方式实现消息传递,而同享内存需要依托于同步。Java提供了synchronized、volatile关键字实现同步。另外volatile关键字还具有1些额外的功能。

5. volatile的使用

在成员变量前加上该关键字便可。

public volatile boolean flag;

6. volatile的特性

6.1 重排序

重排序是计算机为了提高程序履行效力而对代码的履行顺序进行调剂。你以为代码是1行行顺序履行的,但实际并不是如此,重排序详解请移步至:Java并发编程的艺术(2)——重排序

若两行指令之间没有依赖关系,那末计算机可以对他们的顺序进行重排序,但如果两行之间的某个变量被volatile修饰后,重排序规则会产生变化。

在以下情况下,即便两行代码之间没有依赖关系,也不会产生重排序:

  • volatile读

    • 若volatile读操作的前1行动volatile读/写,则这两行不会产生重排序
    • volatile读操作和它后1行代码都不会产生重排序
  • volatile写

    • volatile写操作和它前1行代码都不会产生重排序;
    • 若volatile写操作的后1行代码为volatile读/写,则这两行不会产生重排序。

6.2 可见性

甚么是内存可见性?

“内存可见性”指的是1条线程修改完1个同享变量后,另外一个线程若访问这个变量将会访问到修改后的值。即:1条线程对同享变量的修改,对其他线程立便可见。

但如果未对同享变量采取同步机制,那末同享变量的修改不会对其他线程立便可见。

为何会出现内存不可见的情况?

通过上文可知,在Java中每条线程都有各自独立的存储空间,另外还有1个所有线程同享的内存空间。 
当开启线程时,系统会将同享内存中的所有同享变量拷贝1份到线程专属的存储空间中。接下来该线程在结束前的所有操作都是基于自己的存储空间进行的。因此,若1条线程改变了1个同享变量,仅仅改变的是这条线程专属存储空间中的变量值;此时若其他线程访问这个变量,访问的依然是先前从同享存储空间读出来的值。 
但是我们希望1条线程将某个同享变量修改后,其他线程能立即访问到这个最新的值,而不是失效值。 
这时候就需要同步机制来解决这个问题。

如何确保同享变量的可见性?

要确保所有同享变量对所有线程是可见的,就需要给所有同享变量使用同步。在Java中你可以选择将同享变量用同步代码块包裹或用volatile修饰同享变量。

为何volatile能保证同享变量的内存可见性?

volatile修饰了1个成员变量后,这个变量的读写就会比普通变量多1些步骤。

  • volatile变量写 
    当被volatile修饰的变量进行写操作时,这个变量将会被直接写入同享内存,而非线程的专属存储空间。

  • volatile变量读 
    当读取1个被volatile修饰的变量时,会直接从同享内存中读,而非线程专属的存储空间中读。

通过对volatile变量读写的限制,就可以保证线程每次读到的都是最新的值,从而确保了该变量的内存可见性。

volatile变量赠送的附加功能

进行volatile写操作时,不但会将volatile变量写入同享内存,系统还会将当前线程专属空间中的所有同享变量写入同享内存。 
进行volatile读操作时,系统也会1次性将同享内存中所有同享变量读入线程专属空间。 
这就意味着,如果普通变量在volatile写操作之前被修改,那末在volatile读操作以后就可以正确读到他们。 
但是,在volatile写操作以后被修改的普通变量 和 在volatile读操作之前被访问的普通变量 都不具有内存可见性。

6.3 原子性

甚么是原子性?

原子性指的是1组操作必须1起完成,中途不能被中断。

volatile能确保long、double读写的原子性

在Java中的所有类型中,有long、double类型比较特殊,他们占据8字节(64比特),其余类型都小于64比特。在32位操作系统中,CPU1次只能读取/写入32位的数据,因此对64位的long、double变量的读写会进行两步。在多线程中,若1条线程只写入了long型变量的前32位,紧接着另外一条线程读取了这个只有“1半”的变量,从而就读到了1个毛病的数据。 
为了不这类情况,需要在用volatile修饰long、double型变量。

在内存可见性与原子性上,volatile就相当因而同步的setter和getter函数。但其实不具有volatile的重排序规则,同步块只确保同步块内部的指令不产生重排序,其实不确保同步块之外的指令的重排序。

PS1:Java中的byte居然是字节,bit才是比特(位)。 
PS2:char和short⑵字节、int和float⑷字节、long和double⑻字节、byte⑴字节

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

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

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

相关文章

Java历经20年沧桑,将持续革新

对于企业界来说,很多服务器都部署着Java应用程序,许多物联网设备也都是基于Java技术开发。 20年前,Java为人们带来前所未有的科技理念:一次编写,到处运行。 在此之前,编程语言的种类寥寥无几,…

Java开发中定时器的使用

在JAVA中实现定时器功能要用的2个类是Timer,TimerTask Timer类是用来履行任务的类,它接受1个TimerTask做参数 Timer有两种履行任务的模式,最经常使用的是schedule,它可以以两种方式履行任务:1:在某个时间(Data),2:在某个固定的时间以后(int delay).这两种…

Java虚拟机组成详解

一、jvm的主要组成部分 类加载器(ClassLoader)运行时数据区(Runtime Data Area)执行引擎(Execution Engine)本地库接口(Native Interface) 接下来我们来看以上4个主要组成部分的用途…

取消android所有动画,android studio 取消BottomNavigationView的动画等

app:labelVisibilityMode"labeled"布局文件上添加上此句就可以让标签文字也显示出来了,但是缩放动画,还是会存在。那么回到初始化view的activity中BottomNavigationView navView findViewById(R.id.nav_view);//设置选中时的效果navView.setI…

android addtextchangedlistener参数,【Android】关于addTextChangedListener()方法的上机记录...

自己在学习控件的时候,学到关于EditText的addTextChangedListener()方法,想做一个类似发微博限制字数为140那样的功能,以此文记录上机过程中发现的一些问题。在做这个的时候,是第五节课视频刚提到addTextChangedListener()这个方法…

鸿蒙系统打通iOS,库克真的做到了!正式官宣确认截胡鸿蒙OS系统:软硬件生态全打通...

【4月25日讯】相信大家都知道,自从苹果正式举办完春季新品发布会以后,很多网友们都纷纷吐槽到“苹果的黑科技就是以换色为本,iPhone12推出紫色版本,而iMac也变成了彩虹色,很好的继承了诺基亚“科技以换壳为本”理念”&…

html标签中的文本框的值,HTML文本框的值分配给div标签的标题

线2:#msdhoni我want-什么,当用户输入一些东西在文本框(以行1)应该成为div的标题(在第2行)点击botton(在第1行)。其实想要用代码中的文本输入替换#msdhoni。jQuery代码我米使用:(请建议在这段代码的变化,使这成为可能)String.proto…

快速了解Java集合框架

1. 简介 JDK1.2 引入了 Java 集合框架,包含一组数据结构。与数组不同,这些数据结构的存储空间会随着元素添加动态增加。其中,一些支持添加重复元素另一些不支持,一些支持 null,一些能自动升序打印元素。 所有这些数据…

偷用计算机作文,偷玩电脑作文5篇

偷玩电脑作文5篇篇一:偷玩电脑的滋味星期天,我在家里看电视,妈妈很晚才回来,我只好在家等,看了一会,电视节目没了,我把电视关掉,看了会书消磨时间,我又写了会作业&#x…

钢铁厂计算机相关岗位需要倒班吗,钢铁厂工人倒班的三个阶段,请对号入座!...

原标题:钢铁厂工人倒班的三个阶段,请对号入座!刚开始钢铁厂倒班工作,感觉倒班好,夜班有啥,通宵可以感受夜的宁静,深夜闲暇之余还可以仰望星空,思考人生,白天自由时间多&a…

计算机文化基础B卷期末,《计算机文化基础》上机试卷B

课程代码: 座位号:新疆大学2008- 2009 学年度第一学期期末考试《计算机文化基础》上机试卷姓名: 学号: 专业:学院: 班级:2008年 12月注意事项:在试卷上必须注明学号、姓名否则成绩以“零”分计算完成以下各题后,将应用程序窗口最小…

win7查看 本地计算机策略,win7系统本地组策略编辑器打不开怎么办

本地组策略编辑器是win7系统的管理控制台,通过本地组策略编辑器可以禁止通过本地组策略、禁止对某些任务使用脚本等设置。有些win7 64位系统的用户发现,本地组组策略编辑器打不开了,这是怎么回事呢?会出现这种情况很有可能是控制台…

计算机打字测速,电脑的打字测速软件分享

对于电脑工作人员来说,打字是我们每天都会接触的,作为网站编辑来说,每天就是打字,打字,打字,因此,打字速度一定不能慢,不然就会大大的影响工作效率。下面是学习啦小编为大家整理的关…

2012服务器系统安装iis,Windows Server 2012服务器管理系统安装配置IIS8.5教程

IIS8.0是windows Server2012自带的服务器管理系统,和以往不同,IIS8.0安装和操作都比较简单,界面很简洁,安装也很迅速。今天我们重点完整的演示下windows server 2012上面配置IIS8.5的详细安装。windows server 2012上面配置IIS8.5…

Java9个异常处理的最佳实践

在本文中,作者介绍了9个处理异常的最佳方法与实践,以举例与代码展示结合的方式,让开发者更好的理解这9种方式,并指导读者在不同情况下选择不同的异常处理方式。 以下为译文: Java中的异常处理不是一个简单的话题。初学…

小白零基础怎么学习Java?不要慌

近年来,Java视频逐渐取代了“书籍”的作用,许多初学者已经将视频视为最重要的学习方式。然而,通过对java自学的长期观察和研究,我们发现书籍和视频都有自己的作用。阅读和观看视频对于Java学习者来说是不可或缺的。但是&#xff0…

服务器的虚拟内存怎么调,服务器的虚拟内存怎么调才好

服务器的虚拟内存怎么调才好 内容精选换一换华为云帮助中心,为用户提供产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题、视频帮助等技术文档,帮助您快速上手使用华为云服务。开启弹性云服务器的虚拟内存后,会导致硬盘…

Java小白零基础学习如何突破自己的方法

有很多Java程序员在学习之初经常对如何学习感到困惑。本文将分析如何学习Java编程,并相信它可以帮助处于混乱状态的初学者。 I.培养兴趣 兴趣是可以让你继续前进的动力。如果你只是把这个程序写成谋生手段,那么你将会非常疲惫,更关心这个行…

修改epo服务器 gps,epo

EPO是促红细胞生成素(Erythropoietin)的英文简称。人体中的促红细胞生成素是由肾皮质肾小管周围间质细胞和肝脏分泌的一种激素样物质,能够促进红细胞生成。服用促红细胞生成素可以使患肾病贫血的病人增加血流比溶度(即增加血液中红细胞百分比)。人体缺氧时&#xff…

ug使用服务器系统,ug服务器设置教程视频

ug服务器设置教程视频 内容精选换一换本教程旨在演示使用GDS(General Data Service)工具将远端服务器上的数据导入GaussDB(DWS)中的办法,帮助您学习如何通过GDS进行数据导入的方法。在本教程中,您将:生成本教程需要使用的CSV格式的数据源文件…