// 先上代码
1 public class NoVisibility {
private static boolean ready;
private static int number;

private static class ReaderThread extends Thread {
public void run() {
while(!ready) {
Thread.yield();
}
System.out.println(number);
}
} public static void main(String[] args) {
new ReaderThread().start();
number = 100;
ready = true;
}
}

上边的代码,如果直接运行,main进程首先开始ReaderThread进程,再去设置ready为true。

直观感受应该是当main进程将ready设为true后,ReaderThread进程就会跳出while循环,从而输出number值100。

但实际上,程序可能一直无限循环,或是输出的值为0. 因为这里没有用到同步机制,main进程写的ready和number值,不能保证ReaderThread看到。

为什么?

这里在多线程的背景下,JVM可能会进行底层的字节代码的优化和重排序,所以developer如果没有设计合理的同步机制,就不能确保代码的执行顺序是按照你所写的那样。

怎么做?

最基本的方法,就是用Locking机制,分别在读取和设置变量的方法上设置同一个锁,这就能保证 变量在进程A释放锁前的改动, 进程B在获得锁(同一个锁)后也能读取到。

另外一种常见的方法,就是将 可能被不同的进程读取的变量用volatile修饰,volatile可以近似看作一种轻量级的同步机制。 此外volatile用来告诉编译器和运行库这个变量会在多个进程间共享,

不要将它缓存在寄存器或是其他进程看不到的cache里。

需要注意的是volatile只能保证可见性,不能保证原子性(比如 volatile int a = 0; a++;  两个进程可能都同时读到0),所以它是轻量级的同步机制。

volatile的实现原理

  如果大家有兴趣查看代码JIT生成后的汇编指令,会发现针对volatile的变量的写操作,会有一个Lock指令,这是用来实现内存屏障的,保证如果一个处理器修改了变量值,会直接将值写回到内存,其他的处理器对应的缓存也会失效,需要重新从内存中读取,这样就保证所有的处理器读到的值,都是最近的变量值。

JAVA 多线程随笔 (一) 可见性和volatile关键字的更多相关文章

  1. Java多线程学习(三)volatile关键字

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  2. JAVA多线程基础学习三:volatile关键字

    Java的volatile关键字在JDK源码中经常出现,但是对它的认识只是停留在共享变量上,今天来谈谈volatile关键字. volatile,从字面上说是易变的.不稳定的,事实上,也确实如此,这个 ...

  3. Java多线程学习(二)synchronized关键字(2)

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  4. Java多线程学习(二)synchronized关键字(1)

    转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...

  5. Java多线程之内存可见性和原子性:Synchronized和Volatile的比较

    Java多线程之内存可见性和原子性:Synchronized和Volatile的比较     [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article ...

  6. 细说Java多线程之内存可见性

    编程这些实践的知识技能,每一次学习使用可能都会有新的认识 一.细说Java多线程之内存可见性(数据挣用)         1.共享变量在线程间的可见性                共享变量:如果一个 ...

  7. java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析

    java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java ...

  8. Java并发编程(六)volatile关键字解析

    由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识. 一.内存模型的相关概念 Java内存模型规定所有的变量都是存在 ...

  9. Java并发机制(3)--volatile关键字与内存模型

    Java并发编程:volatile关键字解析及内存模型 个人整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3920373.html 1.线程内存模型: ...

随机推荐

  1. ASP.net如何保证EF操作类线程内唯一

    说到线程内唯一,肯定会想到单例模式,但是如果多用户访问网站就会出现问题.ASP.net中有两种方法可以保证EF操作类线程内唯一(目前只会这两种,以后有好的方法再添加): 1.httpcontext(实 ...

  2. 安装tomcat

    一.JDK1.7安装 1.下载jdk,下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u1-download-513 ...

  3. js_保留关键字

    网页可以被我们分为三个大的部分:结构,表现,形式而js就是专对于表现的,js是一门编程的解释性脚本语言,和其他的语言相同js也有自己的保留的关键字,下面我们来看看js保留的关键字吧!js一共有56个关 ...

  4. 【Spring】非Spring IOC容器下获取Spring IOC上下文的环境

    前言 在Spring Web项目中,有些特殊的时候需要在非Spring IOC容器下获取Spring IOC容器的上下文环境,比如获取某个bean. 版本说明 声明POM文件,指定需引入的JAR. & ...

  5. InstallShield 2015 LimitedEdition VS2012 覆盖安装

    转载:http://tieba.baidu.com/p/3596681127 1. 在General Information里,修改Product Version为新的版本号,此版本号应大于旧的版本号 ...

  6. CSS篇

    一.盒子模型: 标准模式和混杂模式(IE).在标准模式下浏览器按照规范呈现页面:在混杂模式下,页面以一种比较宽松的向后兼容的方式显示.混杂模式通常模拟老式浏览器的行为以防止老站点无法工作. CSS盒子 ...

  7. windows平台解决quick3.5final + sublimeText3 模拟器找不到的问题

    下载了quick3.5 准备在sublime上进行开发,结果发现quick3.5中的player模拟器不见了,原来模拟器移到了quick引擎主目录下的 /tools/simulator/runtime ...

  8. NSJSONSerialization(json序列化)

    //通过调用isValidJSONObject来判断Foundation对象是否可以转换为JSON数据 NSJSONSerialization isValidJSONObject:obj 我们能利用N ...

  9. C#知识点总结系列:5、CLR的组成和运转

    clr基本 CLR(Common Language Runtime)是一个可由多种编程语言使用的“运行时”.(例如:c#,c++/cli,vb,f#,ironpython,ironruby,il... ...

  10. Cocos2d-x 核心概念 - 游戏循环与调度

    每一个游戏程序都有一个循环在不断运行,他是由导演对象来管理和维护. 如果需要场景中的精灵运动起来,我们可以在循环中使用定时器(Scheduler)对精灵等对象的运行进行调度 因为Node中封装了 Sc ...