java如何彻底理解volatile(java关键字volatile三种用法)

技术Java Volatile关键字如何理解Java Volatile关键字如何理解,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。正文在谈

很多新手对于如何理解JavaVolatile关键词不是很清楚。为了帮助大家解决这个问题,下面小编就为大家详细讲解一下。需要的人可以从中学习,希望你能有所收获。

正文

在谈论Volatile之前,我们先来回顾一下Java内存模型的三个要素:原子性、可见性和有序性,这是我们经常提到的并发编程的三个要素。

并发编程的三要素

1.原子性

和数据库事务中的原子性一样,满足原子性特征的操作是不能中断的,要么所有操作都成功,要么所有操作都失败。

只有简单的读取和赋值(数字必须赋给变量,变量之间的赋值不是原子操作)才是原子操作。

比如:

I=2;j=I;我;I=I 1;

在以上四个操作中,i=2是读操作,必须是原子操作。如果你认为这是原子操作。其实分为两步。一种是读取I的值,然后赋给j,这是两步操作,不是原子操作。I和i=i 1实际上是等价的。读取I的值,加1,然后写回主存。这是一个三步走的操作。

因此,在上面的例子中,最终值可能会有很多情况,只是因为原子性无法得到满足。

非原子操作会有线程安全问题,所以我们需要用同步化技术把它变成原子操作。java的并发包提供了一些原子类,比如AtomicInteger、AtomicLong等。

00-1010当多个线程访问同一个共享变量时,如果一个线程修改了这个共享变量的值,其他线程可以立即获得修改后的值。

00-1010编译器和处理器会对指令序列进行重新排序,以优化程序性能,也就是说,您编写的代码序列与您最终执行的指令序列不一致。但是,重排序过程不会影响单线程程序的执行,反而会影响多线程并发执行的正确性。

2.可见性

Volatile是Java语言的类型修饰符。一旦共享变量(类的成员变量和类的静态成员变量)被Volatile修改,它就有两层语义:

1.确保多线程下的可见性。

2.禁止对指令进行重新排序(即保证顺序)。

在这里,我们需要注意一个问题。挥发只能让他修饰的内容看得见、有条不紊。Volatile只能保证单个读/写的原子性,我这个操作不能保证原子性。

3.有序性

JavaVolatile关键字如何理解

**Java内存模型(JMM)**是一个抽象的概念,实际上并不存在。它描述了一套规则或规范。通过这组规范,定义了程序中各种变量(包括实例字段、静态字段和构成数组对象的元素)的访问方法。

尽量屏蔽各种硬件和操作系统之间的内存访问差异,让Java程序在各种平台下都能达到一致的内存访问效果。

Java内存模型规定,所有变量都存储在主内存,每个线程都有自己的工作记忆。线程的工作内存保存着线程中使用的变量的主内存副本。线程对变量的所有操作都必须在工作内存中进行,而不是直接读写主内存。不同的线程不能直接访问对方工作内存中的变量,线程之间的变量传递需要自己的工作内存和主内存之间的数据同步。

主存主要存储Java实例对象,线程创建的所有实例对象都存储在主存中,不管实例对象是方法中的成员变量还是局部变量(也叫局部变量),当然也包括共享类信息、常量和静态变量。因为它是一个共享数据区,所以多个线程在访问同一个变量时可能会发现线程安全问题。

工作内存每个线程都有自己的工作内存(工作内存,也称为本地内存,可以与前面提到的处理器缓存进行比较)。线程的工作内存在线程使用的变量的主内存中保存共享变量的副本。

工作记忆是JMM的一个抽象概念,并不真正存在。它涵盖了高速缓存、写缓冲区、寄存器以及其他硬件和编译器优化。

存储当前方法的所有局部变量信息(工作内存在主内存中存储变量的副本)。每个线程只能访问自己的工作内存,也就是说,线程中的局部变量对其他线程是不可见的。即使两个线程正在执行同一段代码,它们也会在自己的工作内存中创建属于当前线程的本地变量,包括字节码行号指示符和相关的Native方法信息。

Volatile

Volatile 保证内存可见性

Java Volatile关键字如何理解">

主内存和工作内存之间的交互有具体的交互协议,JMM定义了 八种操作 来完成,这八种操作是 原子的 、 不可再分的 ,它们分别是:lockunlockreadloaduseassignstorewrite

其中,lock , unlock , read , write 作用于主内存; load ,use , assign , store 作用于工作内存。

(1) lock

将主内存中的变量锁定,为一个线程所独占。

(2) unclock

将lock加的锁定解除,此时其它的线程可以有机会访问此变量。

(3) read

将主内存中的变量值读到工作内存当中。

(4) load

将read读取的值保存到工作内存中的变量副本中。

(5) use

将值传递给线程的代码执行引擎。

(6) assign

将执行引擎处理返回的值重新赋值给变量副本。

(7) store

将变量副本的值存储到主内存中。

(8) write

将 store 存储的值写入到主内存的共享变量当中。

  • 从主存复制变量到当前工作内存(read and load)

  • 执行代码,改变共享变量值 (use and assign)

  • 用工作内存数据刷新主存相关内容 (store and write)

指令规则

  • read 和 load、store 和 write 必须成对出现。

  • assign 操作,工作内存变量改变后必须刷回主内存。

  • 同一时间只能运行一个线程对变量进行 lock,当前线程 lock 可重入,unlock 次数必须等于 lock 的次数,该变量才能解锁。

  • 对一个变量 lock 后,会清空该线程工作内存变量的值,重新执行 load 或者 assign 操作初始化工作内存中变量的值。

  • unlock 前,必须将变量同步到主内存( store/write 操作)。

Volatile源码案例

Java Volatile关键字如何理解

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/154817.html

(0)

相关推荐

  • 独特的近义词是什么,别具一格的近义词是什么

    技术独特的近义词是什么,别具一格的近义词是什么词目:别具一格拼音:biéjùyīgé类别:成语释义:别独特的近义词是什么,其它。具,另有。比喻另有一种独特的风格(风味)。出处:清·吕留良《与施愚山书》:“咏见赠诗,风力又

    生活 2021年10月21日
  • 怎么搭建Solr8与ikanalyzer

    技术怎么搭建Solr8与ikanalyzer今天就跟大家聊聊有关怎么搭建Solr8与ikanalyzer,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。服务安装并启

    攻略 2021年10月19日
  • R语言做文本挖掘 Part4文本分类

    技术R语言做文本挖掘 Part4文本分类 R语言做文本挖掘 Part4文本分类Part4文本分类
    【发现有人转载,决定把格式什么重新整理一遍,有时间做个进阶版文本挖掘,恩!原文地址:CSDN-R语言做文

    礼包 2021年12月18日
  • JNA在Linux和MAC怎么编译C

    技术JNA在Linux和MAC怎么编译C这篇文章主要讲解了“JNA在Linux和MAC怎么编译C”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JNA在Linux和MAC怎

    攻略 2021年11月30日
  • 怎么使用Python构建可扩展的社交媒体情感分析服务

    技术怎么使用Python构建可扩展的社交媒体情感分析服务本篇文章为大家展示了怎么使用Python构建可扩展的社交媒体情感分析服务,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。探索

    攻略 2021年10月26日
  • 一语成,历史上有哪些一语成谶的事

    技术一语成,历史上有哪些一语成谶的事隶属于昆明陆军总司令部的第四方面军组建于1945年3月5日一语成,仅仅一个多月后,方面军司令官王耀武就指挥所部在湘西大破日寇,一举取得雪峰山大捷,8月在芷江出席日军投降的草签仪式,不久

    生活 2021年10月30日