开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
有序性
有序性概念
有序性(Ordering):是指程序中代码的执行顺序,Java在编译时和运行时会对代码进行优化(重排序)来加快速度,会导致程序终的执行顺序不一定就是我们编写代码时的顺序
instance = new SingletonDemo() 是被分成以下 3 步完成
memory = allocate(); 分配对象内存空间
instance(memory); 初始化对象
instance = memory; 设置 instance 指向刚分配的内存地址,此时 instance != null
步骤2 和 步骤3 不存在数据依赖关系,重排与否的执行结果单线程中是一样的。这种指令重排是被 Java 允许的。当 3 在前时,instance 不为 null,但实际上初始化工作还没完成,会变成一个返回 null 的getInstance。这时候数据就出现了问题。
有序性演示
jcstress是java并发压测工具。wiki.openjdk.java.net/display/Cod… 修改pom文件,添加依赖
有如下代码
1、实际上上面两个方法会有很多线程来执行,为了讲解方便,我们只提出线程1和线程2来讲解。
2、I_Result 是一个保存int类型数据的对象,有一个属性 r1 用来保存结果,在多线程情况下可能出现几种结果?
情况1:线 程1先执行actor1,这时ready = false,所以进入else分支结果为1。
情况2:线程2执行到actor2,执行了num = 2;和ready = true,线程1执行,这回进入 if 分支,结果为 4。
情况3:线程2先执行actor2,只执行num = 2;但没来得及执行 ready = true,线程1执行,还是进入 else分支,结果为1。
情况4:0,发生了指令重排
pos_1处代码和pos_2处代码没有什么数据依赖关系,或者说没有因果关系。Java可能对其进行指令重排,排成下面的顺序。
此时如果线程2先执行到ready = true;还没来得及执行 num = 2; 。线程1执行,直接进入if分支,此时num默认值为0。 得到的结果也就是0。