简单了解java volatile关键字实现的原理

一、volatile关键字的语义分析

1.保证可见性

对共享变量的修改,其他线程能够马上感知到。但不能保证原子性(i++)

2.保证有序性

3.volatile的原理和实现机制

有volatile修饰的共享变量进行写操作的时候会多出有 “lock”标志的汇编代码,Lock前缀的指令在多核处理器下会引发两件事情:

1)将当前处理器缓存行中的数据写回到系统内存中

2)这个写回内存的操作会使在其他cpu里缓存了该内存地址的数据无效。

二、volatile的使用场景

1.状态标志(开关模式)  

package com.roy.http;
public class ShutDownDemmo extends Thread{
  private volatile boolean state = false;
  @Override
  public void run() {
    while(state){
      System.out.println("我在做工作");
    }
  }
  public void shutDown(){
    state = false;
  }
}

当调用shutDown方法时,里面只有一个赋值操作,所以它是原子性的,同时state字段是volatile的,所以当值发生变化时其它线程会立即察觉到。

2.双重检查锁定(double-checked-locking)

package com.roy.http;
public class Singleton {
  private volatile static Singleton instance;
  public static Singleton getInstance(){
    if (instance==null) {
      synchronized (Singleton.class) {
        instance = new Singleton();
      }
    }
    return instance;
  }
}

单例模式中使用双重检查锁定。

三、volatile和synchronized的区别

1.使用上的区别

volatile只能修饰变量,而synchronized只能修饰方法和语句块。

2.对原子性的保证

volatile不能保证原子性,synchronized保证了原子性。

3.对可见性的保证

两者都能保证可见性,但实现原理不同

volatile对变量添加了lock,synchronized使用monitorenter和monitorexit。

4.对有序性的保证

volatile能保证有序,synchronized也能保证有序,但是代价大

5.其他

synchronized会引起阻塞,volatile不会引起阻塞。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java关键字volatile和synchronized作用和区别

    volatile是变量修饰符,而synchronized则是作用于一段代码或方法:如下三句get代码: int i1; int geti1() {return i1;} volatile int i2; int geti2() {return i2;} int i3; synchronized int geti3() {return i3;} geti1() 得到存储在当前线程中i1的数值.多个线程有多个i1变量拷贝,而且这些i1之间可以相互不同.换句话说,另一个线程可能已经改变了它线程内的i1

  • Java中的关键字volatile详解

    volatile关键字经常用来修饰变量.不过,volatile本身很容易被误用.本篇就介绍一下volatile的原理和使用方式. 在介绍volatile关键字原理前,我们首先要了解JVM运行时的内存分配逻辑. 对于成员变量i,它存储在堆内存中.每个线程在运行时都会有一个自己的线程栈,线程如果要访问类的成员变量i,会通过引用获取到堆中变量i实际的值10,然后把这个变量值拷贝到自己的栈内存中,作为一个变量副本,之后线程便不再会与堆中的变量有实际联系.每个线程都有一个自己的本地副本,相互隔离.线程访问

  • Java中volatile关键字实现原理

    前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.concurrent包的核心,没有volatile就没有这么多的并发类给我们使用. 本文详细解读一下volatile关键字如何保证变量在多线程之间的可见性,在此之前,有必要讲解一下CPU缓存的相关知识,掌握这部分知识一定会让我们更好地理解volatile的原理,从而更好.更正确地地使用volatile关键字. CPU缓存 CPU缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为C

  • Java开发中的volatile你必须要了解一下

    前言 上一篇文章说了 CAS 原理,其中说到了 Atomic* 类,他们实现原子操作的机制就依靠了 volatile 的内存可见性特性.如果还不了解 CAS 和 Atomic*,建议看一下我们说的 CAS 自旋锁是什么 并发的三个特性 首先说我们如果要使用 volatile 了,那肯定是在多线程并发的环境下.我们常说的并发场景下有三个重要特性:原子性.可见性.有序性.只有在满足了这三个特性,才能保证并发程序正确执行,否则就会出现各种各样的问题. 原子性,上篇文章说到的 CAS 和 Atomic*

  • C++中volatile关键字及常见的误解总结

    前言 近期看到C++标准中对volatile关键字的定义,发现和java的volatile关键字完全不一样,C++的volatile对并发编程基本没有帮助.网上也看到很多关于volatile的误解,于是决定写这篇文章详细解释一下volatile的作用到底是什么. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier.这是 BS 在 "The C++ Programming Language&

  • java同步之volatile解析

    问题 (1)volatile是如何保证可见性的? (2)volatile是如何禁止重排序的? (3)volatile的实现原理? (4)volatile的缺陷? 简介 volatile可以说是Java虚拟机提供的最轻量级的同步机制了,但是它并不容易被正确地理解,以至于很多人不习惯使用它,遇到多线程问题一律使用synchronized或其它锁来解决. 了解volatile的语义对理解多线程的特性具有很重要的意义,所以彤哥专门写了一篇文章来解释volatile的语义到底是什么. 语义一:可见性 前面

  • Java中Volatile关键字详解及代码示例

    一.基本概念 先补充一下概念:Java内存模型中的可见性.原子性和有序性. 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情.为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制. 可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的.也就是一个线程修改的结果.另一个线程马上就能看到.比如:用volatile修饰的变量,就会具有可见性.volatile修饰的

  • 简单了解java volatile关键字实现的原理

    一.volatile关键字的语义分析 1.保证可见性 对共享变量的修改,其他线程能够马上感知到.但不能保证原子性(i++) 2.保证有序性 3.volatile的原理和实现机制 有volatile修饰的共享变量进行写操作的时候会多出有 "lock"标志的汇编代码,Lock前缀的指令在多核处理器下会引发两件事情: 1)将当前处理器缓存行中的数据写回到系统内存中 2)这个写回内存的操作会使在其他cpu里缓存了该内存地址的数据无效. 二.volatile的使用场景 1.状态标志(开关模式)

  • Java Volatile关键字实现原理过程解析

    volatile的用法 volatile通常被比喻成"轻量级的synchronized",也是Java并发编程中比较重要的一个关键字.和synchronized不同,volatile是一个变量修饰符,只能用来修饰变量.无法修饰方法及代码块等. volatile的用法比较简单,只需要在声明一个可能被多线程同时访问的变量时,使用volatile修饰就可以了. 如以下代码,是一个比较典型的使用双重锁校验的形式实现单例的,其中使用volatile关键字修饰可能被多个线程同时访问到的single

  • 详解Java volatile 内存屏障底层原理语义

    目录 一.volatile关键字介绍及底层原理 1.volatile的特性(内存语义) 2.volatile底层原理 二.volatile--可见性 三.volatile--无法保证原子性 四.volatile--禁止指令重排 1.指令重排 2.as-if-serial语义 五.volatile与内存屏障(Memory Barrier) 1.内存屏障(Memory Barrier) 2.volatile的内存语义实现 六.JMM对volatile的特殊规则定义 一.volatile关键字介绍及底

  • java volatile关键字的含义详细介绍

    java volatile关键字 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和 volatile 关键字机制. synchronized  同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程能够用 synchron

  • java volatile关键字使用方法及注意事项

    java volatile关键字使用方法及注意事项 什么是volatile关键字 volatile 关键字在多线程程序中起着很重要的作用.当多个线程操作同一个变量时,每个线程将拥有对那个变量的本地缓存拷贝,因此,当某一个线程修改了这个变量的值时,实际上修改的是它本地缓存中的变量值,而不是主内存中的变量值,操作这个变量的其他线程并不知道这个变量的值被改变了.为了避免这种情况,我们可以用 valatile 关键字声明这个变量,用 valatile 声明了这个变量之后,变量将不在本地缓存中保存,而在主

  • 简单了解Java多态向上转型相关原理

    这篇文章主要介绍了简单了解Java多态向上转型相关原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 多态性是面向对象的第三大特征. 多态的优点 改善代码的组织结构和可读性. 能够创建可扩展的程序.(随时可以加入新功能) 消除类型之间的耦合关系. 说实话,作为小白的我,并不太能够理解上面三个优点.随着深入学习,理解应该会越来越深吧,共勉. 向上转型 概念 Java允许把子类对象赋值给父类的引用变量,不用做任何强制转换,系统自动完成.向上转型来自

  • 简单分析Java的求值策略原理

    形参和实参 java在定义方法时可以设置参数,参数分为形参和实参,形参是指在定义函数时用于接收外部传入数据的参数,而实参是指在调用方法时主调函数向被调函数传递的数据参数. 例如: public class Main { public static void main(String[] args) { int a = 2; int b = 3; System.out.println(sum(a,b));//5 } private static int sum(int i1,int i2){ ret

  • 简单了解java volatile

    内存模型基本概念 计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入.由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度.因此在CPU里面就有了高速缓存. 并发编程中的三个概念 1、原子性 即一个操作或者多个操作,要么全部执行并且执行的过程不会被

  • java volatile关键字作用及使用场景详解

    1. volatile关键字的作用:保证了变量的可见性(visibility).被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象.如以下代码片段,isShutDown被置为true后,doWork方法仍有执行.如用volatile修饰isShutDown变量,可避免此问题. public class VolatileTest3 { static class Work { boolean isShutDown = false; void shutdown(

  • Java Volatile关键字同步机制详解

    Volatile关键字--最轻量级的同步机制1.保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的.(实现可见性) 例如:如果一个oldvalue -->修改为newvalue ,这时的newvalue可以被其他的线程看到. 2.volatile不是线程安全的,只能保证对单次读/写的原子性.i++ 这种操作不能保证原子性.(不能保证原子性)最常使用场景:一写多读代码演示Volatile的可见性 public class VolatileCa

随机推荐