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关键字解析
随机推荐
- Django学习笔记之CBV和FBV
FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以不再赘述. CBV CBV(class base v ...
- Web前端学习笔记之jQuery选择器
JQuery过滤器 经过一晚上的查找整理,终于整理出一套应该算最全面的JQuery选择过滤器的方法了.所有代码均经过测试.首先HTML代码 HTML Code <html><head ...
- xshell ssh 上传文件
一.通过xshell ssh 上传文件 [lxk@localhost ~]$ yum install lrzsz 安装 [lxk@localhost ~]$ rz 上传文件
- virtualbox安装centos7使用nat+hostonly的网络模式
win环境下的virtualbox下载地址:http://download.virtualbox.org/virtualbox/5.2.0/VirtualBox-5.2.0-118431-Win.ex ...
- 《学习OpenCV3》目录和全书划分
一 概述 1. Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ...
- 20145301Java课程总结
20145301 Java课程总结 每周读书笔记链接汇总 第一周读书笔记: http://www.cnblogs.com/5301z/p/5248888.html 第二周读书笔记: http://ww ...
- 20145310第一周JAVA实验报告
20145310第一周JAVA实验报告 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序. 实验要求 使用JDK和IDE编译.运行简单 ...
- C++开学第二次作业(5.14)
开学第二次作业(5.14) 代码传送门 题目 给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转.例如:给定L为1→2→3→4→5→6,K为3,则输出应该为3→2→1→6→5→4:如果K为 ...
- nuget sources
https://docs.microsoft.com/en-us/nuget/tools/cli-ref-sources https://gemfury.com/help/nuget-server/ ...
- JDK 中的监控与故障处理工具-02 (jps)
jps : JVM Process Status Tool jps 命令可以列出正在运行的虚拟机进程, 并显示虚拟机执行的 main class 的名称(main函数所在的类),以及这些进程的本地虚拟 ...