volatile关键字解析(一)
引起线程并发问题,可以简单的总结为以下三条:
- 原子性问题
- 可见性问题
- 有序性问题(重排序问题)
原子性问题
什么是原子性?
原子性,即一个操作或者多个操作,要么全部执行并且执行过程中不会被任何因素打断,要么全部都不执行。
如常见的银行转账、count++操作等,都必须具备原子性才能保证不出现意外。
A向B转账100元,需要保证两步:A账户减100,B账户加100,如果有任何一个发生意外,总有不满意的一方,A账户减了100,B账户没有加100,客户肯定不满意;A账户由于某种原因没有减100,但是B账户却加了100,银行此时肯定也不干(毕竟是国内,你懂得)。
可见性问题
什么是可见性?
可见性是指当多个消除访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看到修改的值。
同样举个例子来说明一下:
public class RunThread extends Thread {
private boolean isRunning = true;
public boolean isRunning() {
return isRunning;
}
public void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
@Override
public void run() {
System.out.println("进入到run方法中了");
while (isRunning == true) {
}
System.out.println("线程执行完成了");
}
}
public class TestRun
{
public static void main(String[] args) {
try {
RunThread thread = new RunThread();
thread.start();
Thread.sleep(100);
thread.setRunning(false);
} catch (Exception e) {
e.printStackTrace();
}
}
}
我们会发现,RunThread线程无法正常结束了,进入了死循环了。这是由于在主线程中修改的isRunning值,并没有及时对RunThread线程感知到,这就是可见性的问题,由于主线程修改了之后,RunThread线程并没有立即能看到。
有序性问题
什么是有序性?
有序性即程序执行的顺序按照代码的先后顺序执行。
int a = 0;
int b = 0;
a = 1; //语句1
b = 2; //语句2
int c = a * a;//语句3
int d = b + c;//语句4
从上述代码看,语句1在语句2之前执行,但是对于JVM来说情况未必如此,这就是指令重排序。
volatile使用场景
当需要避免并发时发生意想不到的结果,必须要保证以上三条都满足,否则极有可能得到你不想要的结果,我们常用的操作有synchronized和lock来保证这些情况,但是有些情况下,我们其实可以使用轻量级并发volatile关键字,
但是它并不能保证原子性操作,因此,volatile并不能替代synchronized。
关于volatile使用的场景:
- 对变量的写操作不依赖于当前值
- 该变量没有包含在具有其他变量的不变式中
常见的场景有:
- 状态标记变量(如上文提到的RunThread例子中可以对isRunning变量使用volatile关键字)
- 单例中双重检查锁,见(http://www.cnblogs.com/woniu4/p/8287484.html)
什么是指令重排序呢?简单多说,就是处理器为了提升程序的运行效率,可能对输入的代码进行优化,它不保证程序各个语句的执行先后顺序同代码中的顺利一致,但保证最后的结果和顺序执行是一直的。
由于语句4依赖于语句3,则两者的顺序是不会调整的。
volatile关键字解析(一)的更多相关文章
- Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- (转)Java并发编程:volatile关键字解析
转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...
- volatile关键字解析(转)
volatile关键字解析 转载:http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在J ...
- Java并发编程 Volatile关键字解析
volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了 ...
- Java并发编程:volatile关键字解析(转载)
转自https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 Java并发编程:volatile关键字解析 ...
- Java并发编程学习:volatile关键字解析
转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile ...
- Java并发编程:volatile关键字解析-转
Java并发编程:volatile关键字解析 转自海子:https://www.cnblogs.com/dayanjing/p/9954562.html volatile这个关键字可能很多朋友都听说过 ...
- Java并发编程之三:volatile关键字解析 转载
目录: <Java并发编程之三:volatile关键字解析 转载> <Synchronized之一:基本使用> volatile这个关键字可能很多朋友都听说过,或许也都用过 ...
- Java 并发:volatile 关键字解析
摘要: 在 Java 并发编程中,要想使并发程序能够正确地执行,必须要保证三条原则,即:原子性.可见性和有序性.只要有一条原则没有被保证,就有可能会导致程序运行不正确.volatile关键字 被用来保 ...
- Java并发编程:volatile关键字解析(学习总结-海子)
博文地址:Java并发编程:volatile关键字解析
随机推荐
- Linux数据备份与恢复
Linux数据备份及服务器重要数据类别分析 对 Linux 服务器来讲,当然最理想的就是把整块硬盘中的数据都备份,甚至连分区和文件系统都备份,这样如果硬盘损坏,那么我们可以直接把备份硬盘中的数据导入损 ...
- java 与C# 时间格式 交互
方法一 C#端代码 IsoDateTimeConverter convert = new IsoDateTimeConverter(); string ret = JsonConvert.Serial ...
- 【c++ primer, 5e】【try语句块】
p172~p177:c++的try语句块和异常处理: 1.通常,与用户交互的代码和对象相加(底层的代码)是分离开的,异常由与用户交互的代码处理(底层代码抛出异常就可以了). 2.C++的runtime ...
- 20145328 《Java程序设计》第8周学习总结
20145328 <Java程序设计>第8周学习总结 教材学习内容总结 第十四章 NIO与NIO2 NIO使用频道(channel)来衔接数据节点,对数据区的标记提供了clear(),re ...
- spring cron表达式及解析过程
1.cron表达式 cron表达式是用来配置spring定时任务执行时间的字符串,由5个空格分隔成的6个域构成,格式如下: {秒} {分} {时} {日} {月} {周} 每一个域的含义解释 ...
- DOS/BAT批处理if exist else 语句的几种用法
在DOS批处理命令中常常会通过if语句来进行判断来执行下面的命令, 那么批处理if语句怎么用呢,下面学无忧小编就来说说有关批处理if以及if exist else语句的相关内容.一.批处理if书写格式 ...
- 如何使用JMX监控Kafka
使用kafka做消息队列中间件时,为了实时监控其性能时,免不了要使用jmx调取kafka broker的内部数据,不管是自己重新做一个kafka集群的监控系统,还是使用一些开源的产品,比如yahoo的 ...
- UVA 12657 Boxes in a Line(双向链表+小技巧)
题意:对于一行按照顺序排列盒子数字与位置都为 1,2,3,4....n 执行四种操作 c = 1 x 放到 y 的左边 c =2 x 放到 y 的右边 c =3 交换 x, y c =4 ...
- 如何利用mixin编写media query的代码
mixins允许文档作者定义的属性对时可以在其他规则集中重用的模式. Media Queries直译就是“媒体查询”.media就是来指定特定的媒体类型,如屏幕(screen),或者“TV”等,其中“ ...
- 在Windows使用VC编译ICU
1 编译过程在Cygwin下进行,所以必须得安装Cygwin,并且加上Automake, autoconf, make, ar等选项 2 打开命令行窗口,设置环境变量,主要是可以启动cygwin的ba ...