指令重排序 as-if-serial
笔者认为看完一本书或刚要了解完一个知识点 最好自己先运行一些DEMO 自己尝试着去了解下各种意思 这样知识点最终一定是你的。靠死记硬背的讨论或简单的粗暴的看下资料 脑子里肯定还是一团浆糊。
p.p1 { margin: 0; font: 11px Monaco }
p.p2 { margin: 0; font: 11px Monaco; min-height: 15px }
p.p3 { margin: 0; font: 11px Monaco; color: rgba(78, 144, 114, 1) }
p.p4 { margin: 0; font: 11px Monaco; color: rgba(126, 80, 79, 1) }
p.p5 { margin: 0; font: 11px Monaco; color: rgba(119, 119, 119, 1) }
p.p6 { margin: 0; font: 11px Monaco; color: rgba(147, 26, 104, 1) }
span.s1 { color: rgba(147, 26, 104, 1) }
span.s2 { text-decoration: underline }
span.s3 { color: rgba(126, 80, 79, 1) }
span.s4 { color: rgba(0, 0, 0, 1) }
span.s5 { color: rgba(3, 38, 204, 1) }
span.s6 { color: rgba(57, 51, 255, 1) }
span.s7 { color: rgba(145, 175, 203, 1) }
span.Apple-tab-span { white-space: pre }
public class FinalDemo {
// FinalDemo finalDemo;
// public final String b;
//
// public FinalDemo() {
// Random rw = new Random();
// int p = rw.nextInt(10);
// b="helloWorld"+p;
// }
//
// public void write() {
//
// finalDemo=new FinalDemo();
// }
public void doMethodParam( Product product) {
//String obj=b;
// Random rw = new Random();
// int p = rw.nextInt(10);
Product totalMoney=product;
System.out.println("线程:"+Thread.currentThread().getName()+"----money:"+totalMoney.getMoney() + "-----------before---" );
System.out.println("线程:"+Thread.currentThread().getName()+"----money"+totalMoney.getMoney() + "-----------end---" );
}
@Test
public void testFinalMethodParam() {
Thread[] thread=new Thread[4];
for(int i=0;i<4;i++) {
thread[i] = new Thread(new Runnable() {
@Override
public void run() {
int a=new Random().nextInt(10);
// TODO Auto-generated method stub
Product product=new Product();
product.setName("name_"+a);
product.setMoney("10"+a);
doMethodParam(product);
}
});
thread[i].start();
}
}
class Product{
private String name;
private String money;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMoney() {
return money;
}
public void setMoney(String money) {
this.money = money;
}
}
}
打印结果:
线程:Thread-0----money:8-----------before---
线程:Thread-2----money:9-----------before---
线程:Thread-2----money9-----------end---
线程:Thread-0----money8-----------end---
线程:Thread-1----money:8-----------before---
线程:Thread-3----money:5-----------before---
线程:Thread-1----money8-----------end---
线程:Thread-3----money5-----------end---
p.p1 { margin: 0; font: 12px ".PingFang SC"; color: rgba(69, 69, 69, 1) }
span.s1 { font: 12px "Helvetica Neue" }
从上述的打印结果 你看懂了什么。
总结如下:
1)上述中下行有两行before内容,并没有中规中矩的先before再end 说明了一个知识点:程序在执行过程中被指令重排序了。主要原因是编译器或处理器为了优化性能对指令序列进行排序的手段。
2)但是大家有没有观察到虽然表现为重排序 但同一个线程最终执行的结果是一样的,并不因为多线程的影响把值给改掉。这是因为JMM内存模型决定的。对于局部变量和方法参数都是线程私有的并不会被其他线程共享。
3)还有一点as-if-serial语义。不管怎么重排序 对于那种有依赖关系的单线程程序的执行结果不会被改变。处理器能保证对于有依赖关系的指令禁止重排序
指令重排序 as-if-serial的更多相关文章
- JVM学习(八)指令重排序
一.数据依赖性 在学习JVM的指令重排序之前,我们先了解一下什么是数据依赖性: 编译器和处理器在处理具体的指令时,可能会对操作进行重排序来提高执行性能[多条指令并行执行,所以提升性能的同时也可能会导致 ...
- Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)
一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...
- Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)
一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...
- 指令重排序及Happens-before法则随笔
指令重排序 对主存的一次访问一般花费硬件的数百次时钟周期.处理器通过缓存(caching)能够从数量级上降低内存延迟的成本这些缓存为了性能重新排列待定内存操作的顺序.也就是说,程序的读写操作不一定会按 ...
- 深入浅出Java并发包—指令重排序
前面大致提到了JDK中的一些个原子类,也提到原子类是并发的基础,更提到所谓的线程安全,其实这些类或者并发包中的这么一些类,都是为了保证系统在运行时是线程安全的,那到底怎么样才算是线程安全呢? Java ...
- JVM并发机制的探讨——内存模型、内存可见性和指令重排序
并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”. 从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CP ...
- 深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则
转: http://www.blogjava.net/xylz/archive/2010/07/03/325168.html 在这个小结里面重点讨论原子操作的原理和设计思想. 由于在下一个章节中会谈到 ...
- 关于volatile的可见性和禁止指令重排序的疑惑
在学习volatile语义的可见性和禁止指令重排序的相关测试中,发现并不能体现出禁止指令重排序的特性 实验代码如下 package com.aaron.beginner.multithread.vol ...
- 轻松学JVM(二)——内存模型、可见性、指令重排序
上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...
- java指令重排序的问题
转载自于:http://my.oschina.net/004/blog/222069?fromerr=ER2mp62C 指令重排序是个比较复杂.觉得有些不可思议的问题,同样是先以例子开头(建议大家跑下 ...
随机推荐
- Canal Admin
一.Canal Admin 安装与配置 1.1 下载 wget https://github.com/alibaba/canal/releases/download/canal-1.1.4/canal ...
- 第7.13节 案例详解:Python类变量
第7.13节 案例详解:Python类变量 上节介绍了类变量的定义和使用方法,并举例进行了说明.本节将通过一个更完整的例子来说明. 一. 定义函数dirp def dirp(iter): ret ...
- PyQt(Python+Qt)学习随笔:QTableWidgetItem的构造方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTableWidgetItem类为QTableWidget类的项实例类,用于保存表格部件的信息.项 ...
- PyQt学习随笔:ListView控件的视图和数据模型分离案例
Qt 中view类控件的目的是实现数据和模型分离,控件展示数据,数据保存在数据存储中,数据存储中的数据改变了,则控件中展示的数据跟随改变.当设计时只指定了一个控件和一个数据存储关联时,这种分离虽然也能 ...
- PyQt(Python+Qt)学习随笔:Designer中的QDialogButtonBox的StandardButtons标准按钮
在Qt Designer中,可以在界面中使用QDialogButtonBox来配置一组按钮进行操作,Qt中为QDialogButtonBox定义了一组常用的标准按钮,可以在Designer中直接在St ...
- Flask flask-migrate 数据库迁移
简介 flask-migrate是flask的一个扩展模块,主要是扩展数据库表结构的. 官方文档:http://flask-migrate.readthedocs.io/en/latest/ 使用: ...
- vue props默认值国际化报错
未做国际化处理 tabLabel: { type: Array, default: () => (["a", "b", "c"]) } ...
- 数组编程题(github每日一题)
/** * 随机生成一个长度为 10 的整数类型的数组,例如 [2, 10, 3, 4, 5, 11, 10, 11, 20], * 将其排列成一个新数组,要求新数组形式如下,例如 [[2, 3, 4 ...
- C#软件性能优化
C#软件性能优化 1. 性能 衡量一个软件系统性能的常见指标有:响应时间.负载.资源使用率.并发数.在软件中有具体的提高性能需求时,我们需分析该系统性能的影响由哪些因素组成,再针对各部分进行性能 ...
- 第二章、 Centos 6.8安装 Docker
2.1检查Docker的先决条件 64位 CPU计算机(x86_64),不支持32位 CPU 运行Linux 3.8 或更高版本内核. 内核必须支持一种合适的存储驱动(storage driver), ...