// 先上代码
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. eclipse安装Veloeclipse

    step 1.Help-->install new software-->Add Name:Veloeclipse Value:http://veloeclipse.googlecode. ...

  2. svn: 期望文件系统格式在“1”到“4”之间;发现格式“6”

    svn 客户端浏览的时候出现了这个提示,经查,发现是Subversion 1.7 < TortoiseSVN 1.8导致的,需要更换版本,应该是 Version(Subversion) > ...

  3. window 常用快捷键

    1.新建文件夹  ctrl+shift+n 2.删除文件夹  ctrl+d 3.打开命令行  窗口+r 4.关闭命令行  命令行内输入exit然后回车 5.快捷键操作浏览器 1)ctrl+w关闭当前标 ...

  4. iOS定时器的使用

    iOS开发中定时器经常会用到,iOS中常用的定时器有三种,分别是NSTime,CADisplayLink和GCD. NSTimer 方式1 // 创建定时器 NSTimer *timer = [NST ...

  5. SAML 2.0 setup steps, 效果图

    Steps of setting up SAML SSO. 效果图 # Registry a Identity Provider services in:(Might need purchase) I ...

  6. 关于工程结合git的配置

    我们通常把代码放到git sever中,(scm manager)中,上传,下载代码, 可是通常工程的代码改动会有图标提示,改动过的,或者新增的,那么需要在eclipse的工程中做一下简单配置 1,工 ...

  7. Navigator

      Navigator   这是一个简单的例子,用Navigator来跳转页面,页面之间传递参数 (代码是ES6语法写的): import React from 'react'; import { V ...

  8. 关于DSP的boot mode / boot loader /上电顺序 /在线升级等问题的总结

    使用器件 ti dsp c2000 2837x 1.dsp的上电过程和boot mode以及boot loader 1)dsp的上电顺序, 对于双核系统而言 , 他的上电启动顺序如下所示: 系统复位或 ...

  9. td在relative模式下,IE9不显示border

    方法一 .thisTd {    background-clip: padding-box;     position:relative; } 方法二 .thisTd {   z-index=-1; ...

  10. 不完全解决Android微信HTML5 播放视频的问题(不显示控制条,可交互)

    首先你需要知道以下内容: http://ad.weixin.qq.com/learn/2-3-3--%E9%80%9A%E7%94%A8%E5%BA%93 这是微信为广告商开放的API,我一直认为只有 ...