Java 指令重排
Java 指令重排
package com.feshfans;
/**
* 用来演示指令重排
* 指令重排会发生在两个阶段:
* 1. 编译期(jvm 加载字节码时)
* 2. cpu 执行期
* 但对于单线程来说,不管发生怎样的重排,都必须保持与源代码一致的输出结果(As-If-Serial).
* 上述规则保证了单线程的执行结果总是与预期一致,但在多线程的情况,就会出现与预期不一致的情况,
* 而导致这一情况发生的原因,正是指令重排
*
*/
public class InstructionReOrder {
static Integer a = 0;
static Integer b = 0;
static Integer x = 0;
static Integer y = 0;
private void showReOrder() throws InterruptedException {
for(int i=0;i<Integer.MAX_VALUE;i++){
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// 有可能发生重排,即 先执行 x = b,再执行 a = 1
a = 1;
x = b;
}
});
Thread t2= new Thread(new Runnable() {
@Override
public void run() {
// 有可能发生重排,即先执行 y = a,再执行 b = 1;
b = 1;
y = a;
}
});
t1.start();
t2.start();
t1.join();
t2.join();
/**
* 如果没有指令重排,输出的可以结果为:(0,1)(1,1)(1,0)
* 但实际上有可能会输出(0,0)
*/
System.out.println("第 "+ i + "次,x="+x +", y="+y);
if(x == 0 && y == 0){
break;
}
a = b = 0;
x = y = 0;
}
}
public static void main(String[] args) {
InstructionReOrder reOrder = new InstructionReOrder();
try {
reOrder.showReOrder();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出结果如下:

从上图中可以看出,执行到第 65456 次时,发生了指令重排
Java 指令重排的更多相关文章
- 一篇讲Java指令重排和内存可见性的好文
在这里: http://tech.meituan.com/java-memory-reordering.html 指令重排和内存可见性(缓存不一致)是两个不同的问题. volatile关键字太强,即阻 ...
- Java内存模型与指令重排
Java内存模型与指令重排 本文暂不讲JMM(Java Memory Model)中的主存, 工作内存以及数据如何在其中流转等等, 这些本身还牵扯到硬件内存架构, 直接上手容易绕晕, 先从以下几个点探 ...
- Java并发编程(五)JVM指令重排
我是不是学了一门假的java...... 引言:在Java中看似顺序的代码在JVM中,可能会出现编译器或者CPU对这些操作指令进行了重新排序:在特定情况下,指令重排将会给我们的程序带来不确定的结果.. ...
- Java并发:volatile内存可见性和指令重排
volatile两大作用 1.保证内存可见性 2.防止指令重排 此外需注意volatile并不保证操作的原子性. (一)内存可见性 1 概念 JVM内存模型:主内存和线程独立的工作内存 Java内存模 ...
- Java中指令重排
/** * 指令重排:代码执行顺序与预期不一致 (发生在前后行代码无联系时) * 目的:提高性能 * */ public class HappenBefore { private static int ...
- Java 多线程 -- 指令重排(HappenBefore)
指令重排是指:代码执行顺序和预期不一致. 代码运行一般步骤为: 1.从内存中获取指令解码 2.计算值 3.执行代码操作 4.把结果写回内存 而写回内存的操作比较耗时,CPU为了性能,可能不会等它完成, ...
- JVM内存模型、指令重排、内存屏障概念解析
在高并发模型中,无是面对物理机SMP系统模型,还是面对像JVM的虚拟机多线程并发内存模型,指令重排(编译器.运行时)和内存屏障都是非常重要的概念,因此,搞清楚这些概念和原理很重要.否则,你很难搞清楚哪 ...
- happens-before规则和指令重排
...
- JVM内存模型、指令重排、内存屏障概念解析(转载)
在高并发模型中,无是面对物理机SMP系统模型,还是面对像JVM的虚拟机多线程并发内存模型,指令重排(编译器.运行时)和内存屏障都是非常重要的概念,因此,搞清楚这些概念和原理很重要.否则,你很难搞清楚哪 ...
随机推荐
- Spring Cloud负载均衡:使用zuul作服务器端负载均衡
1.目的: 本文简述Spring Cloud负载均衡之服务器负载均衡模式,使用组件为zuul. zuul作为Spring Cloud中的网关组件,负责路由转发.身份验证.请求过滤等等功能,那么我们可以 ...
- Oracle 数据字典视图(V$,GV$,X$)
常用的几个数据字典: user_objects : 记录了用户的所有对象,包含表.索引.过程.视图等信息,以及创建时间,状态是否有效等信息,是非DBA用户的大本营.想知道自己有哪些对象,往这里查. u ...
- Web前端学习书籍
<Head First HTML5 Programming> 介绍如何利用HTML5来搭建Web应用,包含JavaScript内容. <CSS禅意花园>: 不是入门的书籍,对C ...
- java:LeakFilling(Springmvc)
1.后台可以同时多个对象接收前端页面的值:(如图两个都打印了) 2.参数绑定的注解,通过该注解可以解决参数名称与controller中形参名称不一致的问题: @RequestParam(name=&q ...
- ABAP的smartform赋值
添加文本后, 在输出选项中指定行/列
- 查找两个有序数组中的第K个元素(find kth smallest element in 2 sorted arrays)
查找两个有序数组中的第K个元素 int FindKth(int a[], int b[], int k, int astart, int aend, int bstart, int bend) { ; ...
- 用SelectSingleNode()方法查找xml节点一直返回null
代码使用如下 XmlNode root = xmlDoc.SelectSingleNode("Project"); 返回的root一直是null 查了xml文件中确实是有Proje ...
- 线程间的协作(wait/notify/sleep/yield/join)(五)
一.线程的状态 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态). New:新建状态,当线 ...
- Mybatis(二) SQL映射文件
SQL映射文件 单条件查询 1. 在UserMapper接口添加抽象方法 //根据用户名模糊查询 List<User> getUserListByName(); 2. 在UserMappe ...
- equals与== 和toString方法
/** * equals()方法的使用 * * 1.java.lang.Object类中的equals()方法的定义: * * public boolean equals(Object obj) { ...