笔者认为看完一本书或刚要了解完一个知识点  最好自己先运行一些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. java并发编程实战《二》java内存模型

    Java解决可见性和有序性问题:Java内存模型 什么是 Java 内存模型? Java 内存模型是个很复杂的规范,可以从不同的视角来解读,站在我们这些程序员的视角,本质上可以理解为, Java 内存 ...

  2. 第8.10节 使用__class__查看Python中实例对应的类

    一. 语法释义 __class__属性很简单,直接返回实例对应的类.语法如下: 实例. class 当不知道一个实例的类名又想对类的部分内容进行访问时可以使用__class__返回类. 注意:是返回实 ...

  3. Python妙用re.sub分析正则表达式匹配过程

    声明:本文所使用方法为老猿自行研究并编码,相关代码版权为老猿所有,禁止转载文章,代码禁止用于商业用途! 在<第11.23节 Python 中re模块的搜索替换功能:sub及subn函数>介 ...

  4. PyQt(Python+Qt)学习随笔:QAbstractItemView的autoScroll和autoScrollMargin属性

    老猿Python博文目录 老猿Python博客地址 QAbstractItemView的autoScroll属性用于确认鼠标在视口边缘时是否自动滚动内容,默认值为True,autoScrollMarg ...

  5. 【.Net Core】开源项目源码--门户网站--精神科医院官网

    项目简介 此项目是一个实际开发招投标项目,汕头大学精神卫生中心.一个门户网站,因为没有投标上所以把源码公开出来分享. Github地址: https://github.com/simawenbo12/ ...

  6. Robot framework 环境搭建+图标处理

    场景:随着现在项目各种赶工,很多时候界面上的功能还没有实现,这时就可以先对接口进行验证,提早发现一些和预期不一致的错误. Robot framework需要的几个知识点: 测试库:RF是大树,测试库就 ...

  7. Day1 【Scrum 冲刺博客】

    (因发作业当天没注意看作业内容,第一天的冲刺博客和第二天的同时发!!!不好意思!!!) 各个成员在 Alpha 阶段认领的任务 方晓莹 搭建社区管理系统的前端框架 登录页开发 管理员模块个人中心开发 ...

  8. 一种不错的 BFF Microservice GraphQL/REST API 层的开发方式

    云原生(Cloud Native)Node JS Express Reactive 微服务模板 (REST/GraphQL) 这个项目提供了完整的基于 Node JS / Typescript 的微服 ...

  9. 利用神经网络算法的C#手写数字识别(二)

    利用神经网络算法的C#手写数字识别(二)   本篇主要内容: 让项目编译通过,并能打开图片进行识别.   1. 从上一篇<利用神经网络算法的C#手写数字识别>中的源码地址下载源码与资源, ...

  10. sudo rm -rf /*含义

    sudo -----  管理员权限 rm ------ remove 移除 rf ------ recursive递归  force强制 /* ------ 目录下所有文档