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.线程内存模型: ...
随机推荐
- django关系对象映射(Object Relational Mapping,简称ORM)
Model 创建数据库,设计表结构和字段 django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表 from django.db import models clas ...
- ASP.net如何保证EF操作类线程内唯一
说到线程内唯一,肯定会想到单例模式,但是如果多用户访问网站就会出现问题.ASP.net中有两种方法可以保证EF操作类线程内唯一(目前只会这两种,以后有好的方法再添加): 1.httpcontext(实 ...
- angularjs的三目运算
前言:前几天写代码的时候遇到一个问题,有一个按钮,有"已关注"和"+关注"两种状态,需要对这两种状态的按钮的背景颜色进行区分,单后点击"已关注&quo ...
- 表单 阻止 技巧 JavaScript js
阻止表单的提交,可以用return false 来进行阻止 长度不低于6,不高于20 if(username.length < 6 || username>20){ alert (&quo ...
- JavaScript浏览器对象(BOM)中有关设备、浏览器屏幕高度和宽度的API介绍
JavaScript世界中,有很多看起来能够帮我们知道网页宽度和高度的API,但太繁多了,而且容易弄混.不容易区分它们.下面我就来介绍一下,这些API到底是什么意思,之间的区别又在哪里. 一.设备的分 ...
- js跨域访问,No 'Access-Control-Allow-Origin' header is present on the requested resource
js跨域访问提示错误:XMLHttpRequest cannot load http://...... No 'Access-Control-Allow-Origin' header is prese ...
- R语言多项式回归
含有x和y这两个变量的线性回归是所有回归分析中最常见的一种:而且,在描述它们关系的时候,也是最有效.最容易假设的一种模型.然而,有些时候,它的实际情况下某些潜在的关系是非常复杂的,不是二元分析所能解决 ...
- C#中浮点数依IEEE-754标准转二进制串 (MODBUS 浮点数转换)
因工作需要,把再串口通信中浮点数与字节流的数据转换函数放在这,转发的,谢谢原作者. 今天花了一天的时间搜罗资料,为了解决一个串口编程的进制转化问题.因为串口传送的浮点数据格式与IEEE-754标准(3 ...
- Hadoop 简介
一个开源的,高可靠,可扩展的分布式计算框架 解决的问题 1 海量数据的存储(HDFS) 2海量数据的分析(Mapreduce) 3 分布式资源调度 (Yarn) 应用场景 日志分析,基于海量数据的在线 ...
- Android sdk目录介绍
android sdk目录介绍 build-tools 各版本SDK编译工具 docs 离线开发者文档Android SDK API参考文档 extras 扩展开发包,如兼容架包. platforms ...