引起线程并发问题,可以简单的总结为以下三条:

  • 原子性问题
  • 可见性问题
  • 有序性问题(重排序问题)

原子性问题

什么是原子性?

原子性,即一个操作或者多个操作,要么全部执行并且执行过程中不会被任何因素打断,要么全部都不执行。

如常见的银行转账、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关键字解析(一)的更多相关文章

  1. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

  2. (转)Java并发编程:volatile关键字解析

    转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...

  3. volatile关键字解析(转)

    volatile关键字解析 转载:http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在J ...

  4. Java并发编程 Volatile关键字解析

    volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了 ...

  5. Java并发编程:volatile关键字解析(转载)

    转自https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析   Java并发编程:volatile关键字解析 ...

  6. Java并发编程学习:volatile关键字解析

    转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile ...

  7. Java并发编程:volatile关键字解析-转

    Java并发编程:volatile关键字解析 转自海子:https://www.cnblogs.com/dayanjing/p/9954562.html volatile这个关键字可能很多朋友都听说过 ...

  8. Java并发编程之三:volatile关键字解析 转载

    目录: <Java并发编程之三:volatile关键字解析 转载> <Synchronized之一:基本使用>   volatile这个关键字可能很多朋友都听说过,或许也都用过 ...

  9. Java 并发:volatile 关键字解析

    摘要: 在 Java 并发编程中,要想使并发程序能够正确地执行,必须要保证三条原则,即:原子性.可见性和有序性.只要有一条原则没有被保证,就有可能会导致程序运行不正确.volatile关键字 被用来保 ...

  10. Java并发编程:volatile关键字解析(学习总结-海子)

    博文地址:Java并发编程:volatile关键字解析

随机推荐

  1. Asp.net Core Windows部署

    一.  IIS 部署模式 1. 安装IIS服务 2. 下载安装Core SDK        https://www.microsoft.com/net/download/Windows/build3 ...

  2. 2009-2010 ACM-ICPC, NEERC, Western Subregional Contest

    2009-2010 ACM-ICPC, NEERC, Western Subregional Contest 排名 A B C D E F G H I J K L X 1 0 1 1 1 0 1 X ...

  3. php实现dota天梯、wow竞技场、lol排位赛匹配加分算法ELO

    public function marchOpponents() { $rstep = Yii::$app->params['ratingStep'];//(随机范围) $rsN=100; $d ...

  4. spring定时器(注解的形式)

    最近有个需求,要在凌晨的时候,根据某几张表生成一张定时任务表里的数据,数据的状态为0(未整改),然后在当天晚上,再把这些数据的状态没改变的,改变状态为1(待整改),然后要用到定时器,百度了一下用注解形 ...

  5. 修改Linux登录提示信息

    佛祖保佑式 cat >> /etc/profile.d/message.sh << END echo -e "\033[33;40;5m _ooOoo_ O88888 ...

  6. 贝叶斯公式由浅入深大讲解—AI基础算法入门【转】

    本文转载自:https://www.cnblogs.com/zhoulujun/p/8893393.html 1 贝叶斯方法 长久以来,人们对一件事情发生或不发生的概率,只有固定的0和1,即要么发生, ...

  7. [Pytorch]PyTorch Dataloader自定义数据读取

    整理一下看到的自定义数据读取的方法,较好的有一下三篇文章, 其实自定义的方法就是把现有数据集的train和test分别用 含有图像路径与label的list返回就好了,所以需要根据数据集随机应变. 所 ...

  8. Linux基础知识点

    1.目录结构 bin 存放二进制可执行文件(ls,cat,mkdir等) boot 存放用于系统引导时使用的各种文件 dev 用于存放设备文件 etc 存放系统配置文件 home 存放所有用户文件的根 ...

  9. POJ2159 ancient cipher - 思维题

    2017-08-31 20:11:39 writer:pprp 一开始说好这个是个水题,就按照水题的想法来看,唉~ 最后还是懵逼了,感觉太复杂了,一开始想要排序两串字符,然后移动之类的,但是看了看 好 ...

  10. "ImportError: cannot import name OVSLegacyKernelSwitch"

    My VirtualMachine OS is Ubuntu14.04, Linux. Recently I want to install the mininet in my OS, and I u ...