笔者认为看完一本书或刚要了解完一个知识点  最好自己先运行一些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的更多相关文章

  1. JVM学习(八)指令重排序

    一.数据依赖性 在学习JVM的指令重排序之前,我们先了解一下什么是数据依赖性: 编译器和处理器在处理具体的指令时,可能会对操作进行重排序来提高执行性能[多条指令并行执行,所以提升性能的同时也可能会导致 ...

  2. Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  3. Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  4. 指令重排序及Happens-before法则随笔

    指令重排序 对主存的一次访问一般花费硬件的数百次时钟周期.处理器通过缓存(caching)能够从数量级上降低内存延迟的成本这些缓存为了性能重新排列待定内存操作的顺序.也就是说,程序的读写操作不一定会按 ...

  5. 深入浅出Java并发包—指令重排序

    前面大致提到了JDK中的一些个原子类,也提到原子类是并发的基础,更提到所谓的线程安全,其实这些类或者并发包中的这么一些类,都是为了保证系统在运行时是线程安全的,那到底怎么样才算是线程安全呢? Java ...

  6. JVM并发机制的探讨——内存模型、内存可见性和指令重排序

    并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”. 从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CP ...

  7. 深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则

    转: http://www.blogjava.net/xylz/archive/2010/07/03/325168.html 在这个小结里面重点讨论原子操作的原理和设计思想. 由于在下一个章节中会谈到 ...

  8. 关于volatile的可见性和禁止指令重排序的疑惑

    在学习volatile语义的可见性和禁止指令重排序的相关测试中,发现并不能体现出禁止指令重排序的特性 实验代码如下 package com.aaron.beginner.multithread.vol ...

  9. 轻松学JVM(二)——内存模型、可见性、指令重排序

    上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...

  10. java指令重排序的问题

    转载自于:http://my.oschina.net/004/blog/222069?fromerr=ER2mp62C 指令重排序是个比较复杂.觉得有些不可思议的问题,同样是先以例子开头(建议大家跑下 ...

随机推荐

  1. 使用Flutter重构斗鱼APP

    Github源码地址:https://github.com/yukilzw/dy_flutter flutter重构的斗鱼直播APP 首页.娱乐为Material组件开发:直播间.鱼吧为纯自定义编写 ...

  2. 第7.17节 Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析

    第7.17节  Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析 静态方法也是通过类定义的一种方法,一般将不需要访问类属性但是类需要具有的一些能力可以静态方法提供. 一 ...

  3. PyQt(Python+Qt)学习随笔:QTreeWidget树型部件中的QTreeWidgetItem项构造方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTreeWidget树型部件的项是单独的类对象,这个类就是QTreeWidgetItem. QTr ...

  4. PyQt(Python+Qt)学习随笔:QTreeView树形视图的autoExpandDelay属性

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTreeView树形视图的autoExpandDelay属性用于控制在视图中拖拽时,当鼠标停留在一 ...

  5. Python学习随笔:获取当前主机名和用户名的方法

    在Python中,要获取当前主机的主机名和登录用户名很简单: 使用os.getlogin():返回当前登录用户名 使用socket.gethostname():返回当前机器主机名 代码如下: > ...

  6. Scrum 冲刺 第七篇

    Scrum 冲刺 第七篇 每日会议照片 昨天已完成工作 队员 昨日完成任务 黄梓浩 初步完成app首页模块的搭建 黄清山 完成部分个人界面模块数据库的接口 邓富荣 完成部分个人界面接口 钟俊豪 完成部 ...

  7. Codeforces Edu Round 47 A-E

    A. Game Shopping 按照题意模拟既可. #include <iostream> #include <cstdio> using namespace std; co ...

  8. Android开源项目分类汇总-转载

    太长了,还是转载吧...今天在看博客的时候,无意中发现了@Trinea在GitHub上的一个项目Android开源项目分类汇总,由于类容太多了,我没有一个个完整地看完,但是里面介绍的开源项目都非常有参 ...

  9. 抖音视频背景音乐提取工具v1.0

    使用方法:id就是你点那个音乐分享,复制链接,然后链接有个ID(userid=后面数字就是id),就是那个,输入ID之后得到链接,浏览器新建下载,复制你得到的链接就行了(结果空白多解析几次就行了)

  10. Linux相关介绍和安装

    目录 前言 第一章 linux介绍 1.1 linux简介 第二章 Linux起源 2.1 Unix的历史 2.2 Unix操作系统的革命 2.3 Linux系统的诞生 2.4 Linux系统的发展史 ...