一.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. 编译 datax

    datax 是阿里巴巴官方开源的一个数据同步工具,可以用于诸多数据源之间的同步,并且使用简单.效率高. datax 官方有提供编译好的版本,可以直接下载,但是其中包含有 BUG. 我最近遇到的一个问题 ...

  2. 邮箱图标的css样式

    <div> <div style="position:relative; height:40px;width: 70px;border:2px solid black; m ...

  3. python 错误、调试、单元测试、文档测试

    错误分为程序的错误和由用户错误的输入引起的错误,此外还有因为各种各样意外的情况导致的错误,比如在磁盘满的时候写入.从网络爬取东西的时候,网络断了.这类错误称为异常 错误处理 参考链接:https:// ...

  4. Python简单的get和post请求

    1.json 模块提供了一种很简单的方式来编码和解码JSON数据. 其中两个主要的函数是 json.dumps() 和 json.loads() , 要比其他序列化函数库如pickle的接口少得多. ...

  5. rabbitmq 实现多个消费队列

    1.将消费程序复制重新生成一个. 2.channel.BasicQos(0, 1, false); 空闲的先消费

  6. js javascript 如何获取某个值在数组中的下标

    js 某个值在数组中的下标javascript中知道一个数组中的一个元素的值,如何获取数组下标JS 获取数组某个元素下标 函数方法 采用prototype原型实现方式,查找元素在数组中的索引值js查找 ...

  7. Qt ini文件

    ini文件格式 节(section) 节用方括号括起来,单独占一行,例如: [section] 键(key) 键(key)又名属性(property),单独占一行用等号连接键名和键值,例如: name ...

  8. CoreData数据库搭建

    1.首先创建父类吧重用的代码写在里边 #import <Foundation/Foundation.h> #import <CoreData/CoreData.h> @inte ...

  9. 汇编之JCC指令

    版权声明:本文为博主原创文章,转载请附上原文出处链接和本声明.2019-09-06,21:59:16.作者By-----溺心与沉浮----博客园 JCC指令决定它跳不跳转跟别的没关系,只跟EFLAG标 ...

  10. 统计代码测试覆盖率-Python

    衡量Unit Test(单元测试)是否充分, 覆盖率是一个必要指标, 是检验单元测试的重要依据, 这里针对python unittest 的单元测试覆盖率coverage进行分享. 来自官方的解释: ...