java中线程之间的共享变量存储在主内存(java堆)中,每个线程都有一个私有的本地内存,本地内存存储了该线程以读、写共享变量的副本。本地内存是一个抽象概念,并不真实存储。它涵盖了cache,寄存器记等等。

线程之间的通信

线程之间的通信采用的是共享内存的方式,整个通信的过程由JMM(java内存模型)来控制的。线程A与线程B之间要通信必须要经历下面两个过程:

  • 线程A把本地内存A中更新过的共享变量刷新到主内存中去
  • 线程B到主内存中读取线程A之前已更新过的共享变量

重排序

java编译器/解释器为了优化程序代码重排序。我们先来看一个例子:

public class Test {
    static boolean flag = true;
    static float money = 0f;
    public static void main(String[] args) {
        flag = false;
        money = 0.5f;
        new Thread() {
            @Override
            public void run() {
                test();
            }
        }.start();
    }

    static void test() {
        while (!flag)
            Thread.yield();
        System.out.println("money == " + money);
    }
}

上面的代码要么输出"money==0.5"(几率很小很小),要么什么都不输出。这是因为编译器可能将flag = false和money = 0.5f进行的重排序。即money = 0.5f出现在了flag=false的前面。这样的话,当mony=0.5f时发生了线程切换,test方法得到了执行。而这是flag值是为true的,所以输出了"money == 0.5"。那么这样的话,我们写的代码得不到控,是不是很无奈。不用担心,JMM提出了happens-before机制。

happens-before

hanppens-before是JMM对程序员做出的保证的。

在一个线程中前一个操作对后一个操作是可见的

a=3;
a=5;

这种操作是前后有依赖性的。先a赋值为3,后又改成5。不管这两行代码将来重排序后,前后顺序发生如何变化,JMM对程序员做出的保证是a=3先执行,a=5后执行。但是向a=3,b=6; 这种前后没有依赖关系的就不能保证执行顺序了。

同一个对象的解锁操作,对其加锁是可见的

加锁和解锁多发生于多线程中,如果对一个对象进行的解锁操作,那么对这个对象的加锁操作一定是可见的。意思是对一个对象的进行解锁操作,则对该对象进行加锁操作时一定能加锁成功的。

如果A happens-before B,且B happens-before C,那么A happens-before C

volatile字段的写入操作happens-before于每一个后续的同一个字段的读操作

最新文章

  1. Mac OS X搭建C#开发环境
  2. 随笔分类 - [C#6] 新增特性
  3. HTML静态网页导航制作
  4. 构建Logstash+tomcat镜像(让logstash收集tomcat日志)
  5. 转:python webdriver API 之定位一组对象
  6. js最好的继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法。
  7. Flex性能优化常用手法总结 转
  8. 关于MessageBox的用法
  9. break和continue 的区别
  10. css 控制文字超出部分显示省略号
  11. 图中最短路径的算法--dijiska算法C语言实现
  12. 【BZOJ2424】[HAOI2010]订货(费用流)
  13. MacBook小技巧
  14. Nginx中文手冊
  15. memcached内存管理机制[未整理]
  16. [转] Java DecimalFormat 用法
  17. js备忘录2
  18. 易懂的modelsim学习笔记
  19. [ShaderStaff] Vignette Effect
  20. 转:centos彻底删除文件夹、文件命令

热门文章

  1. python入门(七):CGI编程
  2. D3D HOOK实现透视讲解
  3. poj_2823 线段树
  4. open live writer 代码着色插件
  5. Chrome浏览器断点调试无效的问题
  6. Jmeter--压测dubbo接口
  7. swift 下storyboard的页面跳转和传值
  8. centos 安装 Vmare tool
  9. 直接IO 零拷贝 DAM 自缓存应用程序
  10. Spark Streaming源码分析 – DStream