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)

相关推荐

  • spark 性能调优高级篇(查询sparksql最新分区)

    技术怎么解析SparkSQL+SequoiaDB 性能调优策略这篇文章将为大家详细讲解有关怎么解析SparkSQL+SequoiaDB 性能调优策略,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后

    攻略 2021年12月17日
  • 有草有水的寓意好的字,姓王想起一个有水有草的女孩名字

    技术有草有水的寓意好的字,姓王想起一个有水有草的女孩名字展开全部 王渃有草有水的寓意好的字, 王淓,两个字就行,以后名字都三个字的,两个字姓名吃香 PS,友情提醒,千万别采纳三个字的名字。。。。看到幼儿园,小学入学名单你

    生活 2021年10月24日
  • 聚焦近义词,“均匀”的近义词是什么

    技术聚焦近义词,“均匀”的近义词是什么jūn yún[释义] (形)分布或分配在各部分的数量相同聚焦近义词,时间的间隔相等。
    均匀的近义词
    近义词:平均、恰当、匀和、匀称、均匀
    一、平均 píngjūn
    (1) 按份儿均

    生活 2021年10月30日
  • 荸荠怎么煮,朋友送了好多马蹄怎么做菜

    技术荸荠怎么煮,朋友送了好多马蹄怎么做菜原料主料荸荠怎么煮:马蹄9个 梨1个 橘子1个 辅料:水适量调料:冰糖适量 详细步骤 1、将马蹄,梨,橘子洗好。
    2、马蹄梨削皮,橘子剥皮。
    3、将马蹄,梨切小块,锅中放水烧开

    生活 2021年10月25日
  • 没有配置环境变量django可以用吗(创建django时如何选择编译器)

    技术启动uwsgi报错提示找不到django的模块怎么办小编给大家分享一下启动uwsgi报错提示找不到django的模块怎么办,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获

    攻略 2021年12月18日
  • 5g有哪三大优势

    技术5g有哪三大优势这篇文章主要介绍“5g有哪三大优势”,在日常操作中,相信很多人在5g有哪三大优势问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”5g有哪三大优势”的疑惑有所帮助!接下来,

    攻略 2021年10月25日