美文网首页AndroidAndroid开发经验谈
Android线程篇(八):原子操作和指令重排

Android线程篇(八):原子操作和指令重排

作者: 小五666 | 来源:发表于2018-03-31 19:25 被阅读273次

本文部分概念参考大神“海 子”博客,感谢作者:
http://www.cnblogs.com/dolphin0520/p/3920373.html

1.原子性操作

来个例子:
张三账户有1000大洋,李四账户有2000大洋,张三要给李四转账100大洋,在这个过程中:
if成功:
1.张三账户:1000-100=900
2.李四账户:2000+100=2100
if失败:
1.张三账户:1000
2.李四账户:2000
我们把这种要么同时成功,要么同时失败要么同时成功的操作叫做具有原子性的操作。

2.指令重排

天天听大神说:指令重排,指令重排到底是个什么鬼?
举个例子:

int i = 0;              
boolean flag = false;
i = 1;                //语句1  
flag = true;          //语句2

上面代码定义了一个int型变量,定义了一个boolean类型变量,然后分别对两个变量进行赋值操作。从代码顺序上看,语句1是在语句2前面的,那么JVM在真正执行这段代码的时候会保证语句1一定会在语句2前面执行吗?不一定,为什么呢?这里可能会发生指令重排序(Instruction Reorder)。

下面解释一下什么是指令重排序,一般来说,处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。

比如上面的代码中,语句1和语句2谁先执行对最终的程序结果并没有影响,那么就有可能在执行过程中,语句2先执行而语句1后执行。

但是要注意,虽然处理器会对指令进行重排序,但是它会保证程序最终结果会和代码顺序执行结果相同,那么它靠什么保证的呢?再看下面一个例子:

int a = 10;    //语句1
int r = 2;    //语句2
a = a + 3;    //语句3
r = a*a;     //语句4

这段代码有4个语句,那么可能的一个执行顺序是:


image.png

那么可不可能是这个执行顺序呢: 语句2 语句1 语句4 语句3

不可能,因为处理器在进行重排序时是会考虑指令之间的数据依赖性,如果一个指令Instruction 2必须用到Instruction 1的结果,那么处理器会保证Instruction 1会在Instruction 2之前执行。

虽然重排序不会影响单个线程内程序执行的结果,但是多线程呢?下面看一个例子:

//线程1:
context = loadContext();   //语句1
inited = true;             //语句2
 
//线程2:
while(!inited ){
  sleep()
}
doSomethingwithconfig(context);

上面代码中,由于语句1和语句2没有数据依赖性,因此可能会被重排序。假如发生了重排序,在线程1执行过程中先执行语句2,而此是线程2会以为初始化工作已经完成,那么就会跳出while循环,去执行doSomethingwithconfig(context)方法,而此时context并没有被初始化,就会导致程序出错。

从上面可以看出,指令重排序不会影响单个线程的执行,但是会影响到线程并发执行的正确性。

为什么要单独讲解原子性呢?原子性在多线程编程中要注意什么问题?如何解决指令重排在多线程下的影响呢?请关注下篇文章。

相关文章

  • Android线程篇(八):原子操作和指令重排

    本文部分概念参考大神“海 子”博客,感谢作者:http://www.cnblogs.com/dolphin0520...

  • JAVA面试

    volatile: 保证可见性 不保证原子性 禁止指令重排序 为什么不保证原子性?因为当一个两个线程一起写入工作内...

  • volatile

    保证内存可见性 禁止指令重排序 不能保证原子性

  • Volatile

    特性 可见性有序性(禁止指令重排) 缺点 不保证原子性 例子

  • 线程同步(锁)

    Java的线程安全性问题主要关注点有3个:可见性、有序性和原子性。 voliate 是由于本身语义禁止了指令重排语...

  • JMM关键技术点

    JMM关键技术点都是围绕着多线程的“原子性”、“可见性”、“有序性”来建立的。 指令重排序 在执行程序时,为了提高...

  • Java指令重排序在多线程环境下的应对策略

    一、序言 指令重排在单线程环境下有利于提高程序的执行效率,不会对程序产生负面影响;在多线程环境下,指令重排会给程序...

  • volatile

    20210822 保证可见性、不保证原子性、防止指令重排 保证可见性 可见性是指当多个线程访问同一个变量时,一个线...

  • Java指令重排序在多线程环境下的应对策略

    一、前言指令重排在单线程环境下有利于提高程序的执行效率,不会对程序产生负面影响;在多线程环境下,指令重排会给程序带...

  • Java指令重排序在多线程环境下的应对策略

    一、前言指令重排在单线程环境下有利于提高程序的执行效率,不会对程序产生负面影响;在多线程环境下,指令重排会给程序带...

网友评论

    本文标题:Android线程篇(八):原子操作和指令重排

    本文链接:https://www.haomeiwen.com/subject/cswhcftx.html