JAVA 多线程随笔 (一) 可见性和volatile关键字
// 先上代码
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关键字的更多相关文章
- Java多线程学习(三)volatile关键字
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- JAVA多线程基础学习三:volatile关键字
Java的volatile关键字在JDK源码中经常出现,但是对它的认识只是停留在共享变量上,今天来谈谈volatile关键字. volatile,从字面上说是易变的.不稳定的,事实上,也确实如此,这个 ...
- Java多线程学习(二)synchronized关键字(2)
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- Java多线程学习(二)synchronized关键字(1)
转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...
- Java多线程之内存可见性和原子性:Synchronized和Volatile的比较
Java多线程之内存可见性和原子性:Synchronized和Volatile的比较 [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article ...
- 细说Java多线程之内存可见性
编程这些实践的知识技能,每一次学习使用可能都会有新的认识 一.细说Java多线程之内存可见性(数据挣用) 1.共享变量在线程间的可见性 共享变量:如果一个 ...
- java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析
java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java ...
- Java并发编程(六)volatile关键字解析
由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识. 一.内存模型的相关概念 Java内存模型规定所有的变量都是存在 ...
- Java并发机制(3)--volatile关键字与内存模型
Java并发编程:volatile关键字解析及内存模型 个人整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3920373.html 1.线程内存模型: ...
随机推荐
- Android Paint的属性
在Paint中有很多的属性可以设置,比如可以设置阴影,颜色过滤等等,这些会产生不同的奇妙效果,今天就对各种属性探索一下. 方法一: 1 //设置绘制的颜色,a代表透明度,r,g,b代表颜色值. 2 s ...
- JAVA应用程序占用CPU、内存过高分析过程
1.查看cpu占有率 top -P 2.查看进程cpu占用率 ps -mp 3749 -o THREAD,tid,time|sort -rn|head -n 20 查看占用cpu高,且占用时间长的线程 ...
- git 设置不需要输入密码
https方式每次都要输入密码,按照如下设置即可输入一次就不用再手输入密码的困扰而且又享受https带来的极速 设置记住密码(默认15分钟): git config --global credenti ...
- redis3.0.6安装(linux和windows)
官网上描述安装方法如下:$ wget http://download.redis.io/releases/redis-3.0.6.tar.gz$ tar xzf redis-3.0.6.tar.gz$ ...
- dsp28377控制DM9000收发数据——第三版程序,通过外部引脚触发来实现中断接受数据,优化掉帧现象
//-------------------------------------------------------------------------------------------- - //D ...
- python非递归全排列
刚刚开始学习python,按照廖雪峰的网站看的,当前看到了函数这一节.结合数组操作,写了个非递归的全排列生成.原理是插入法,也就是在一个有n个元素的已有排列中,后加入的元素,依次在前,中,后的每一个位 ...
- Sprint第三阶段(第四天12.12)
- php : 基础(3)
运算符 算术运算符 基础: 符号有:+ - * / % 说明: 他们都是针对数字进行的运算: 如果他们的两边有不是数字的数据,就会(自动)转换为数字: 其中取余运算(取模运算)%,它只 ...
- 【转载】动态新增svg节点
原文地址:http://blog.csdn.net/tomatomas/article/details/50442497 原文作者:番茄大圣 创建svg节点时,要使用createElementNS函数 ...
- validate插件深入学习-03validate()方法配置项
validate()方法配置项 rules 定义校验规则 messages 定义提示信息 上面这两个已经介绍过了 rules里隐藏的属性depends,只有符合条件(返回true)的时候才会执行 su ...