一.volatile

代码

package jvm;

public class VolatileVisibilityTest {

    private static  boolean initFlag = false;
// private static volatile boolean initFlag = false; public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
public void run() {
System.out.println("waiting data.....");
while(!initFlag) {
}
System.out.println("success.....");
}
}).start(); Thread.sleep(); new Thread(new Runnable() {
public void run() {
prepareData();
} }).start();
} public static void prepareData() {
System.out.println("prapareing data......");
initFlag = true;
System.out.println("prapareing data end......");
}
}

1.不使用volatile,运行结果:

waiting data.....
prapareing data......
prapareing data end......

2.使用volatile,运行结果:

waiting data.....
prapareing data......
prapareing data end......
success.....

JMM数据原子操作

  • read(读取):作用于主内存,它把变量值从主内存传送到线程的工作内存中,以便随后的load动作使用;

  • load(载入):作用于工作内存,它把read操作的值放入工作内存中的变量副本中;

  • use(使用):作用于工作内存,它把工作内存中的值传递给执行引擎,每当虚拟机遇到一个需要使用这个变量的指令时候,将会执行这个动作;

  • assign(赋值):作用于工作内存,它把从执行引擎获取的值赋值给工作内存中的变量,每当虚拟机遇到一个给变量赋值的指令时候,执行该操作;

  • store(存储):作用于工作内存,它把工作内存中的一个变量传送给主内存中,以备随后的write操作使用;

  • write(写入):作用于主内存,它把store传送值放到主内存中的变量中。

  • lock(锁定):作用于主内存,它把一个变量标记为一条线程独占状态;
  • unlock(解锁):作用于主内存,它将一个处于锁定状态的变量释放出来,释放后的变量才能够被其他线程锁定;

voliate缓存可见性实现原理:

底层实现主要是通过汇编lock前缀指令,它会锁定这块区域内的缓存(缓存行锁定)并会回写到主内存。

IA-32架构开发者对lock指令的解释:

1)会将当前处理器缓存行的数据立即写会系统主存

2)这个写回内存的操作会引起在其他cpu里缓存了该内存地址的数据无效(MES协议)

线程2将initFlag的值store到主内存时要通过总线,cpu总线嗅探机制监听到initFlag值被修改,线程1的initFlag失效,线程1需要重新read initFlag的值。

.synchronize

代码:

package concurrent;

public class VolatileAtumicTest {
private static volatile int num = 0;
public static void increse() {
// public static synchronized void increse() {
num++;
} public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[10];
for(int i=0; i<threads.length; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
for(int i=0; i<1000; i++) {
increse();
}
}
});
threads[i].start();
} for(Thread t : threads) {
t.join();
} System.out.println(num);
} }

不加synchronized,输出:

num<=10000

加上synchronized,输出:

10000

Java-volatile底层实现原理的更多相关文章

  1. [Java并发编程(五)] Java volatile 的实现原理

    [Java并发编程(五)] Java volatile 的实现原理 简介 在多线程并发编程中 synchronized 和 volatile 都扮演着重要的角色,volatile 是轻量级的 sync ...

  2. volatile底层实现原理

    前言 当共享变量被声明为volatile后,对这个变量的读/写操作都会很特别,下面我们就揭开volatile的神秘面纱. 1.volatile的内存语义 1.1 volatile的特性 一个volat ...

  3. Java volatile关键字实现原理

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

  4. Hash算法及java HashMap底层实现原理理解(含jdk 1.7以及jdk 1.8)

    现在很多公司面试都喜欢问java的HashMap原理,特在此整理相关原理及实现,主要还是因为很多开发集合框架都不甚理解,更不要说各种其他数据结构了,所以造成面子造飞机,进去拧螺丝. 1.哈希表结构的优 ...

  5. 并发之volatile底层原理

    15.深入分析Volatile的实现原理 14.java多线程编程底层原理剖析以及volatile原理 13.Java中Volatile底层原理与应用 12.Java多线程-java.util.con ...

  6. java并发编程系列七:volatile和sinchronized底层实现原理

    一.线程安全 1.  怎样让多线程下的类安全起来 无状态.加锁.让类不可变.栈封闭.安全的发布对象 2. 死锁 2.1 死锁概念及解决死锁的原则 一定发生在多个线程争夺多个资源里的情况下,发生的原因是 ...

  7. 【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile

    章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译= ...

  8. Java并发机制的底层实现原理之volatile应用,初学者误看!

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

  9. Java volatile 关键字底层实现原理解析

    本文转载自Java volatile 关键字底层实现原理解析 导语 在Java多线程并发编程中,volatile关键词扮演着重要角色,它是轻量级的synchronized,在多处理器开发中保证了共享变 ...

  10. Java并发之底层实现原理学习笔记

    本篇博文将介绍java并发底层的实现原理,我们知道java实现的并发操作最后肯定是由我们的CPU完成的,中间经历了将java源码编译成.class文件,然后进行加载,然后虚拟机执行引擎进行执行,解释为 ...

随机推荐

  1. 基于OceanStor Dorado V3存储之数据保护 Hyper 特性

    基于OceanStor Dorado V3存储之数据保护 Hyper 特性 1.1  快照 1.2  HyperCDP 1.3  HyperCopy 1.4  克隆(HyperClone) 1.5   ...

  2. Elasticsearch(ES) 创建索引

    欢迎关注笔者的公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site/ ...

  3. C++调用linux命令并获取返回值

    qt中封装了相关的方法, 但是因为我的命令中用到了管道命令, 出现了非预期结果, 所有改用了linux系统原生的方法. 下边是一个判断某进程是否存在的例子. 当前存在一个问题,当linux返回多行时, ...

  4. B-Tree详解

    之前写过一篇关于索引的文章<SQL夯实基础(五):索引的数据结构>,这次我们主要详细讨论下B-Tree. B-树 B-tree,即B树,而不要读成B减树,它是一种多路搜索树(并不是二叉的) ...

  5. Python - 迭代器与生成器 - 第十三天

    Python 迭代器与生成器 迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问 ...

  6. Linux帮助——获取帮助

    Linux帮助——获取帮助 摘要:本文主要学习了Linux众多命令中最基础的帮助命令. 介绍 作用 Linux的所有操作都可以通过命令行来完成,所以学习Linux最好从命令行开始.因为Linux的命令 ...

  7. amanda安装

    下载地址 http://www.amanda.org/download.php http://www.zmanda.com/download-amanda.php 编译安装 编译出错: error: ...

  8. Android软件架构

    08_29_Android软件架构 架构的本质 本质, 类似图纸, 不是建筑物: 明确范围 软件设计中, 架构不等于框架: 底层的编码,到设计模式, 到框架,再到架构(微服务,SOA) 好的架构 做好 ...

  9. LoadRunner性能测试工具下载

    LoadRunner性能测试工具 LoadRunner是前美科利(Mercury Interactive)公司著名的性能测试产品.Mercury公司曾经是全球业务优化科技领域的领导者.2006年由惠普 ...

  10. super与this用法

    super注意点: 1.当super调用父类的构造方法,必须在构造方法的第一个: 2.super必须只能出现在子类的方法或者构造方法中: 3.super和this不能同时调用构造方法: 4.super ...