一.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. WPF 中如何变相让 ListBox 宽度(Width) 100%,高度(Height) 100%,从而达到 Filled 的效果

    直接贴代码了: XAML: <Window x:Class="HelloWorld.MainWindow" xmlns="http://schemas.micros ...

  2. 如何配置Memcached高速缓存,加快wordpress的速度

    Memcached是什么 Memcached是一种高性能的分布式内存对象缓存系统.在动态应用,Memcached既能提高访问的速度,同时还减低了数据库的负载.DangaInteractive为提升Li ...

  3. kali渗透综合靶机(二)--bulldog靶机

    kali渗透综合靶机(二)--bulldog靶机 靶机下载地址:https://download.vulnhub.com/bulldog/bulldog.ova 一.主机发现 netdiscover ...

  4. QT+OpenGL(01)--实现三角形渲染

    1.openglwidget.ui <ui version="4.0"> <author/> <comment/> <exportmacr ...

  5. C#通过PInvoke调用c++函数的备忘录

    目前知道的情况被调用的C/C++函数只能是全局函数 不能调用类中的成员方法 被调用的C函数必须使用extern “C“包含,保证采用的导出函数名生成规则和.NET一致 函数调用约定通常使用WINAPI ...

  6. Linux搭建www,mail,ftp三大DNS服务器

    ##############################-----服务器端----###############################1. 安装bind# yum install bin ...

  7. java SSM 框架 微信自定义菜单 快递接口 SpringMVC mybatis redis shiro ehcache websocket

    A 调用摄像头拍照,自定义裁剪编辑头像,头像图片色度调节B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,快速开发利器)+快速表单构建器 freemaker模版技术 ,0个代码不用写,生成 ...

  8. Redis缓存和MySQL数据一致性方案(转)

    需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景,主要 ...

  9. Django框架(十八)—— drf:序列化组件(serializer)

    序列化组件 # 模型层 from django.db import models class Book(models.Model): nid = models.AutoField(primary_ke ...

  10. 数据库-mysql01 简单介绍以及安装部署

    本次mysql数据库安装采用二进制安装(免安装即绿色版),数据库版本是mysql5.7.26 首先下载mysql安装包,然后上传服务器里,最后解压. 卸载centos7自带的数据库软件包: [root ...