java中,volatile关键字有两大作用:

  1.保证线程的可见性

  2.防止指令重排序

这篇文章主要通过典型案例,体现可见性这一特性。

概念:

  java中,堆内存是线程共享的。而每个线程,都应该有自己独享的内存用于工作。所以,当线程访问到堆内存中的共享变量时,会考虑copy一份,存在自己的工作空间中。之后对工作空间中的值进行操作,完成后重新写回到堆内存。

  这样一来,在多线程同时访问这个变量时,就可能出现拿不到实时的值的问题(根本原因在于:本来共享的变量,因为缓存到各个线程的工作空间导致数据在写回之前不互通)。

  而volatile的作用之一,就是解决这一问题。

下面通过一段代码,来展示volatile的这一特性。

 public class HelloVolatile {
private volatile boolean running = true; //开关,表示是否可运行 void m(){
System.out.println("m start");
//一直执行
while(running){ }
//如果running一直未true,下面的代码执行不到
System.out.println("m end");
} public static void main(String[] args) {
HelloVolatile helloVolatile = new HelloVolatile();
//新建线程,run方法调用m方法,running为true时一直循环
new Thread(helloVolatile::m, "非主线程").start();
//休眠1s
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
//主线程设置running为false,如果running不加volatile,则新建的线程是读不到的
helloVolatile.running = false;
}
}

running变量不加volatile的执行结果:

m start

加了volatile的执行结果:

m start
m end

可见性的原理:

MESI(缓存一致性)协议:

  1.写数据时,如果发现操作的是共享变量,会发出信号通知其他CPU设置该变量的缓存行为无效状态。

  2.当其他CPU使用这个变量时,会先去观察是否有更改的信号,当发现缓存行失效时,会从主内存(堆中)重新读取此变量。
volatile的优缺点:

  优点:高效(非锁机制)

  缺点:仅仅保证可见性,不保证数据的一致性。

Volatile关键字回顾之线程可见性的更多相关文章

  1. Volatile 关键字 内存可见性

    1.问题引入 实现线程: public class ThreadDemo implements Runnable { private boolean flag = false; @Override p ...

  2. 全面理解Java内存模型(JMM)及volatile关键字(转载)

    关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoad ...

  3. 全面理解Java内存模型(JMM)及volatile关键字

    [版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772461 出自[zejian ...

  4. 并发之volatile关键字

    volatile关键字 volatile关键字是什么 在上一章我们讲到了并发的的三个概念,那么今天在讲解下在java中可以保证可见性和有序性的一个关键字. volatile关键字 :当变量的值被该关键 ...

  5. Java多线程编程——volatile关键字

    (本篇主要内容摘自<Java多线程编程核心技术>) volatile关键字的主要作用是保证线程之间变量的可见性. package com.func; public class RunThr ...

  6. 全面理解Java内存模型(JMM)及volatile关键字(转)

    原文地址:全面理解Java内存模型(JMM)及volatile关键字 关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型( ...

  7. 双重检查锁单例模式为什么要用volatile关键字?

    前言 从Java内存模型出发,结合并发编程中的原子性.可见性.有序性三个角度分析volatile所起的作用,并从汇编角度大致说了volatile的原理,说明了该关键字的应用场景:在这补充一点,分析下v ...

  8. 浅析Volatile关键字

    浅析Volatile关键字 在java中线程并发中,线程之间通信方式分为两种:共享内存和消息传递.共享内存指的是多个线程之间共享内存的属性状态:消息传递指的是线程之间发送信息来通信.在介绍volati ...

  9. Java volatile关键字实现原理

    场景引入 可见性问题 先来看一张图: 上面的图,是简化版的Java内存模型,一个线程有自己的工作内存,同时还有一个共享的主内存. 线程1和线程2读取数据data时,先从主内存里加载data变量的值到工 ...

随机推荐

  1. Java volatile修饰字段

     一.关键字volatile修饰字段: 使用特殊域变量(volatile)实现线程同步 volatile:不稳定的:反复无常的:易挥发的: 1.volatile关键字为域变量的访问提供了一种免锁机制, ...

  2. legend图例

    import matplotlib.pyplot as plt import numpy as np x=np.linspace(-3,3,50) y1=x*2+1 y2=x**2 plt.plot( ...

  3. loadrunner通过socket测接口

    #include "lrs.h" Action() {     //建立到服务端的连接     lrs_create_socket("socket1",&quo ...

  4. Spring5源码分析(1)设计思想与结构

    1 源码地址(带有中文注解)git@github.com:yakax/spring-framework-5.0.2.RELEASE--.git Spring 的设计初衷其实就是为了简化我们的开发 基于 ...

  5. Coding and Paper Letter(十五)

    资源整理. 1.Nature Climate Change论文"Higher temperatures increase suicide rates in the United States ...

  6. Microsoft Translator:打破语言障碍 拓展全球沟通新机遇

    Translator:打破语言障碍 拓展全球沟通新机遇"> 作者:Olivier Fontana, 微软研究院Microsoft Translator产品战略总监 世界越来越小,全球协 ...

  7. STL标准库中的容器

    容器:顾名思义,我的理解就是把同一种数据类型括起来,作为一捆.如vector<int> ,vector就是个容器,里面全是一个个的int型数据. 容器包括三大块: 顺序型容器: (1)ve ...

  8. 简单的员工管理系统(Mysql+jdbc+Servlet+JSP)

    员工管理系统 因为学业要求,需要完成一个过关检测,但是因为检测之前没有做好准备,且想到之前用mysql+jdbc+Struts2+bootstrap做成了一个ATM系统(主要有对数据的增删改查操作), ...

  9. Docker Compose 项目打包部署

    Docker Compose 前面我们使用 Docker 的时候,定义 Dockerfile 文件,然后使用 docker build.docker run 等命令操作容器.然而微服务架构的应用系统一 ...

  10. 盒马微信小程序

    盒马app刚出现,就吸足了眼球.最近看了看盒马界面,很Q,就想着仿照app写个小程序. 功能介绍 好奇微信小程序是如何制作的,也对盒马app感兴趣,就尝试写了这个盒马小程序.实现了app的部分功能,还 ...