您好、欢迎来到现金彩票网!
当前位置:2019跑狗图高清彩图 > 先行指令站 >

volatile关键字深度讲解

发布时间:2019-07-31 10:18 来源:未知 编辑:admin

  数据执行是在cpu,数据存储在内存,内存给cpu传数据速度慢,cpu速度快,所以在cpu里面有一个缓存,把需要的数据先放在cpu的缓存中,执行结束,一起高速缓存中的结果冲刷到主存中

  Intel 的MESI协议,MESI协议保证了每个缓存中使用的共享变量的副本是一致的。它核心的思想是:当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。

  1.目的:屏蔽各个硬件平台和操作系统的内存访问差异以实现让Java程序在各种平台下都能达到一致的内存访问效果。

  3.Java内存模型并没有限制执行引擎使用处理器的寄存器或者高速缓存来提升指令执行速度,也没有限制编译器对指令进行重排序。

  4.Java内存模型规定所有的变量都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(类似于前面的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存。

  想要并发程序正确地执行,必须要保证原子性、可见性以及有序性。只要有一个没有被保证,就有可能会导致程序运行不正确。

  一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。

  当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

  变量之间的相互赋值不是原子性操作。(x++和 x = x+1包括3个操作:读取x的值,进行加1操作,写入新的值。不是原子操作)

  Java内存模型只保证了基本读取和赋值是原子性操作,如果要实现更大范围操作的原子性,可以通过synchronized和Lock来实现。由于synchronized和Lock能够保证了原子性。

  当一个共享变量被volatile修饰时,它修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。

  而普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主存是不确定的,当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。synchronized和Lock也能够保证可见性

  在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。

  在Java里面,可以通过volatile关键字来保证一定的“有序性”,也可以通过synchronized和Lock来保证有序性。

  Java内存模型具备一些先天的“有序性”,即不需要通过任何手段就能够得到保证的有序性,这个通常也称为 happens-before 原则。如果两个操作的执行次序无法从happens-before原则推导出来,那么它们就不能保证它们的有序性,虚拟机可以随意地对它们进行重排序。

  :一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作

  :如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C

  线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作

  线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生

  线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行

  对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始

  一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

  保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

  当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;

  在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。

  下面这段话摘自《深入理解Java虚拟机》:“观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”

  lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:

  1. 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;

  (1)volatile不适合复合操作:inc++不是一个原子性操作,可以由读取、加、赋值3步组成,

  3.采用java并发包中的原子操作类,原子操作类是通过CAS循环的方式来保证其原子性的

  上面的代码在编译运行时,可能会出现重排序从1-2-3排序为1-3-2。在多线程的情况下会出现以下问题。线行代码时,B线程进来,而此时A执行了1和3,没有执行2,此时B线程判断instance不为null,直接返回一个未初始化的对象。

  Segment的get方法在整个过程中不加锁,除非读到的值为null或者空,才会加锁重新读。

  能够在多线程之间保持可见性,多线程可以同时读,并且读到的都是最新的值,但是只能被单线程写(有一种情况可以被多线程写,就是写入的值不依赖原值),在get操作里只需要读,不需要写count变量。之所以能够保证多线程读到的都是最新的值,是因为根据Java内存模型的happen before原则,对于volatile字段的写入操作先于读操作,也就是说,2个线程同时修改和读取volatile变量的值,写操作先执行,读操作后执行。这就是volatile的经典应用之一。

  比如i++分为:①i取值;②i+1;③结果赋值给i ---volatile操作指保证②③ 没有办法保证①,因为已经读取

  volatile的使用过程中很容易出现的一个问题是:错把volatile变量当做原子变量。主要是因为volatile关键字使变量的读、写具有了“原子性”。然而这种原子性仅限于变量(包括引用)的读和写,无法涵盖变量上的任何操作,即:

  综上,其实volatile保持内存可见性和防止指令重排序的原理,本质上是同一个问题,也都依靠内存屏障得到解决。用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最新值。volatile很容易被误用,用来进行原子性操作。

  被写入 volatile 变量的这些有效值独立于任何程序的状态,包括变量的当前状态。事实上,我的理解就是上面的2个条件需要保证操作是原子性操作,才能保证使用volatile关键字的程序在并发时能够正确执行。

  我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是current包的核心,没有volatile就没有这么多的并发类给我们使用。本文详细解读一下volat...博文来自:DoubleWeiWei001

  对于volatile关键字我们平时很少用到,但是有时候它就派上用场了,所以下面我们浅谈一下(如果你要搞嵌入式编程,抱歉此处小二的层次帮不了你,┭┮﹏┭┮)注:此处使用的是C++编译器没有volatil...博文来自:缥缈烟雨

  volatile关键字在c、java中都有,用于修饰变量,例如privatevolatileinti;它在多处理器开发环境中保证了共享变量的“可见性”,即当一个线程修改一个共享变量时,另外一个变量能读...博文来自:l577217的博客

  Java的volatile关键字在JDK源码中经常出现,但是对它的认识只是停留在共享变量上,今天来谈谈volatile关键字。volatile,从字面上说是易变的、不稳定的,事实上,也确实如此,这个关...博文来自:x

  1、volatile关键字的作用是什么?多线程中的原子性、可见性、有序性分别表示什么意思?volatile关键字的作用:volatile是java中的一个类型修饰符。它是被设计用来修饰被不同线程访问和...博文来自:的博客

  1.synchronized关键字目的:synchronized关键字是java提供的锁机制,主要解决线程的同步问题,那么它可以修饰方法和同步代码块,那么问题来了,我们什么时候用同步代码块和方法呢,我...博文来自:HashMap原理认识

  volatile:保证内存的可见性首先得引入一个概念:寄存器【关于寄存器的一篇博客】当一个变量在内存中创建后,我们可以通过对变量重新赋值的方式,对其值进行改变。#includelt;stdi...博文来自:OddSmurfs的博客

  volatile关键字:当多个线程进行操作共享数据时,可以保证内存中的数据可见。相较于synchronized是一种较为轻量级的同步策略。缺点:1.volatile不具备“互斥性”2.volatile...博文来自:BushRo

  volatile关键字区分C程序员和嵌入式系统程序员的最基本的问题:嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所有这些都要求使用volatile变量。不懂得volatile内容将会带来灾难...博文来自:liaowo8829的博客

  概述:本文主要介绍Java语言中的volatile关键字,内容涵盖volatile的保证内存可见性、禁止指令重排等。...博文来自:代码改变世界

  volatile关键字的作用和原理关键字作用volatile保证可见性一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:保证了不同线程对这个变量进行操...博文来自:MyHerux的博客

  volatile关键字的作用、原理在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到“半个”单例。而发挥神奇作用的volatil...博文来自:u010938610的博客

  volatile关键字的意义在于让被关键字修饰的变量每次使用时都重新去主内存里读取变量,而不是从高速缓存去读取。inta=1;普通变量定义之后,若要使用它,都会先把它的值从主内存拷贝到高速缓存中 每次...博文来自:wssjn1994的博客

  根据《java多线程编程核心技术》整理总结关键字volatile的主要作用是使变量在多个线.volatile关键字简介下面我们通过代码示例来理解volatile关键字的作用publiccl...博文来自:睁眼看世界

  作为一个菜鸟,我学习volatile都只能了解个大概,都是给我一堆花里胡哨的废话,举例没一个是有用的,因此我总觉得volatile关键件没啥卵用,为啥,看看别人给的例子这里有volatile和没vol...博文来自:u013317158的博客

  在多线程中,volatile关键字是很重要的一个知识点,在多线程共享资源的时候,每个线程数据对外都是不可见的,这就容易出现”脏读”现象,其实就是线程私有堆栈中的数据和公共堆栈中的数据不同步造成的.解决...博文来自:charles_lun专栏

  一.volatile关键字是什么?当一个变量定义为volatile之后,它将具备两种特性:  ①保证此变量对所有线程的可见性    当一条线程修改了这个变量的值,新值对于其他线程可以说是可以立即得知的...博文来自:李子的博客

  相信很多人对于volatile关键字既熟悉又陌生,熟悉是对这个名字很熟悉,陌生是对他的原理和用法很陌生,最近几天通过查阅大量资料和书,终于对volatile有了一定的理解,写此博客一来做了记录,二来使...博文来自:阿拉灯神灯的专栏

  1.static关键字当一个进程的全局变量为static之后,它就变成了静态全局变量,静态全局变量和其他的全局变量的存储地点并没有区别,都在.data段(已初始化)或者.bss段(未初始化)内,但是它...博文来自:change

  volatile关键字能保证可见性和有序性,但是不保证原子性。因此并不能保证线程安全。看一个相关的例子:双重校验锁实现的单例模式:publicclassDoubleCheckSymbol{privat...博文来自:风行天下

  前言在Java中,Java中volatile关键字十分重要本文全面amp;详细解析volatile关键字,希望你们会喜欢目录1.定义Java中的1个关键字/修饰符2.作用保证被volatil...博文来自:专注分享 Android开发 干货

  volatile的作用volatile关键字是防止在共享的空间发生读取的错误。只保证其可见性,不保证原子性;使用volatile指每次从内存中读取数据,而不是从编译器优化后的缓存中读取数据,简单来讲就...博文来自:QX_a11的博客

  近些天,学习模拟实现线程池,仅仅听到线程两个字,就让人不寒而栗。刚开始接触多线程编程,确实很难,多线程编程要结合很多很多的计算机底层知识,如操作系统,计算机组成原理等。这篇博客,是我对v...博文来自:飞鸿踏雪泥的博客

  前言:volatile关键字通过内存屏障和禁止重排序来优化实现对volatile变量写操作时,会在写操作后加入一条store屏障指令,将本地内存中的共享变量值刷新到主内存对volatile变量读操作时...博文来自:Jae_Wang的博客

  -Transient关键字Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个...博文来自:龙吟的专栏

  在日常写java代码的环境下(不是研究计算机理论的情况)是会观测到内存可见性所带来的一些问题,比如下面这段代码:publicclassReorderingDemo{staticbooleanflag=...博文来自:WK_SDU的博客

  Java并发编程学习笔记深入理解volatile关键字的作用引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深...博文来自:gavin5033的博客

  内存模型与CPU缓存本来CPU计算的数字都是从主从mainmemory中读取的,但是CPU运行的速度比计算机读取内存的速度快,为了补齐这个短板,所以出现了CPU缓从这种东西。在多CPU系统(或多核处理...博文来自:Matthewhou的专栏

  Volatile关键字的粗浅理解在学习并发编程的时候了解到,volatile关键字有两个作用:1.并发环境可见性:volatile修饰后的变量能够保证该变量在线程间的可见性,线程进行数据的读写操作时将...博文来自:的博客

  在印象中,volatile修改的变量是线程安全的,我一直这么认为,殊不知还有条件的:1.运算结果并不依赖变量的当前值,或者能够确保只有单一线.变量不需要与其他的状态变理共同参与不变约...

  前言在理解volatile前,先理解原子性、可见性、有序性原子性:操作的不可分割性。如++count实际上是可以分割的三个独立操作,读取-gt;修改-gt;写入,其结果依赖之前的状...

  前言对于ThreadLocal、Volatile、synchronized、Atomic这四个关键字,我想一提及到大家肯定都想到的是解决在多线程并发环境下资源的共享问题,但是要细说每一个的特点、区别、...

  大家都知道在多线程高并发下,要保持数据的原子性,不产生脏数据,需要用到加锁机制。一般情况下我们会想到用synchronized关键字来实现。但是也有些人会用volatile关键字,毕竟从性能上来讲vo...

  Java代码在编译后会变成Java字节码,字节码被ClassLoader加载到JVM中,JVM执行字节码,最终要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令...

  最近在研究ConcurrentHashMap的源代码的时候,发现底层实现的Segments使用到了关键字volatile不太明白这个关键字的用法,查了一些资料总结如下:volatile的作用是让变量在...

  在C中会遇到一个一个不是很常用的关键字volatile,如果是仅仅是应用层编程,在控制台打印东西,这个用的不多,但是在C的嵌入式编程这个关键字会很有用,使用它编译器不会对C代码进行优化,老老实实将C直...

  volatile时轻量级的synchronized,它在多处理器开发中保证了数据的读的一致性,意思就是当一个线程修改一个共享变量时,另外一个线程能读到这个共享变量的值。如果volatile变量修饰符使...

  volatile(1)(百度百科)volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。所以volatile关键字的目的是防止被编译器优化。例子:XBYTE...

  1:为什么要引入AtomicInteger关键字  在java中,多个线程访问一个共享变量时会发生线程安全问题。 例子:  Count类: 主函数开三个线程:  我们希望count的值为599,但是由...

  volatile关键字是一种类型修饰符,用它声明的类型变量表示该变量是自由可变的,可能随时会被某些未知的因素所修改,从而强制编译器在对此类型的变量进行访问时,都必须从变量的地址值中取值。=======...

  系列四:地域分布——用SparkSQL和SparkCore(读parquet和日志文件)实现

  系列3:统计各省份数据量的分布情况——存储成json文件格式,存储到mysql中,spark算子的方式进行离线:数据转换为Parquest文件格式,采用Snappy压缩方式,序列化方式采用KroySerializer

  贝叶斯算法 — 朴素贝叶斯分类器— 过滤垃圾邮件 — 流失用户 — 用户画像

  m0_37657725:您好,我想咨询一下实际生产中应该是多少数据需要分表呢?第二个是百万级别的数据应该怎么弄?谢谢您

http://deafbook.net/xianxingzhilingzhan/381.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有