java内存模型浅析

前些日子写了一篇文章分析Java运行时内存区域,让我们对于Java内存有了基本的认识,很多人常常会把两者混淆。经过本篇文章的介绍,相信大家会更加熟悉和了解两者之间的区别。

Java内存模型基础

Java内存模型(JMM),从抽象的角度来看其定义了Java主内存与线程本地内存之间的抽象关系。在之前介绍多线程时有些过一篇关于volatile的文章,有提到主内存、线程本地内存,当时对于两者之间的关系并没有深入介绍,留到介绍内存模型时才来讲解。主内存(Main Memory)指的是所有线程可以共享的内存区域,本地内存(Local Memory)指的是线程本地私有的内存,其存储的是主内存中的一份副本。其实本地内存只是JMM的一个抽象,在物理上根本是不存在的。

Java内存模型

顺序一致性模型

顺序一致性模型是一种理论化模型,其只是作为Java内存模型设计的一种参考。其主要包含两大特性:

1、在一个线程中的所有操作,必须按照程序的顺序来执行;
2、(不管程序是否同步)从每个线程的角度去看所有的操作都是有序的。在顺序一致性模型中所有的操作都具有原子性、而且其结果对所有线程可见。

对于上述第1点,大家都比较好理解,对于单线程来说,我们希望程序执行顺序是有序的。对于第二点,多线程环境下的有序,大家或许会感到疑惑,因为多线程存在并发问题,下面来重点分析这一种情况。
假设在一个程序中存在2个线程,线程A的执行顺序为:A1--->A2--->A3,线程B的执行顺序为:B1--->B2--->B3。若是线程同步的话,A、B线程的执行顺序为(假设A线程先执行):A1--->A2--->A3--->B1--->B2--->B3,符合上述第2点。若是A、B线程并不同步执行的话,情况则不一样了。假设其执行结果为下图:

顺序一致性执行结果

上图可以看出,无论是从线程A还是线程B的角度他们的执行顺序都没有发生变化,论证了上述第二个特性,所有的操作都是按照顺序执行。

happens-before原则

JSR-133内存模型使用happens-before原则来阐述程序执行过程与内存可见行。在JMM中,如果一个操作的执行结果对另外一个操作来说是可见的,那么这两个操作就必须要遵循happens-before规则。需要注意的是,happens-before描述的是操作结果的可见行,并不是操作的执行顺序下面介绍happens-before的具体规则:
程序顺序规则:一个线程中的所有操作,happens-before于该线程中的任意后续操作;
监视器锁规则:对于一个锁的解锁操作,happens-before于随后对其进行加锁的操作;
volatile变量规则:对于一个volatile变量的写操作,happens-before于任意后续对这个变量的读操作;
传递性规则:如果A操作 happens-before B操作,且B操作happens-before C操作,那么A操作 happens-before C操作;

重排序介绍

重排序是指编译器和处理器为了优化程序执行的性能而进行重新排序的一种手段。例如,a=1;b=2;这两个操作,就可能会被编译器或处理器进行重排序,改变其执行顺序。

数据依赖性

数据依赖性简单来说就是两个操作之间对于数据存在依赖,后面的操作依赖于前面的操作。例如,如果两个操作同时访问同一个变量,且其中一个操作为变量的写操作,那么这两个操作之间就存在数据依赖性。下面将举例说明:
写后读: a=1;b=1;
写后写: a=1;a=2;
读后写: a=b;b=1;
上述例子中的两个操作之间是存在数据依赖性的,因为只要改变两个操作执行的顺序那么其结果就会与预期不同。因此编译器与处理器在进行重排序时,必须要遵守数据依赖性。当然这里所说的数据依赖性仅仅针对的是单线程和单个处理器的情况,对于多个处理器和多线程之间的数据依赖性不会被编译器和处理器考虑。

as-if-serial语义

as-if-serial的语义是指不论编译器和处理器如何重排序,对于单线程来说,程序的执行结果都不能被改变。

结束语

写到这里相信大家对于Java内存模型会有一些了解,文章重点在于介绍Java内存模型中的一些理论知识。理解重排序,对于实际开发工作中关于多线程并发同步很有帮助的。对于多线程来说,编译器、处理器的优化不会考虑其数据依赖性,那么就可能改变预期执行结果,需要程序员自己通过同步手段进行控制。从我个人经验来看,对于这些知识的理解,能让自己从使用转向明白为什么的阶段。

参考书籍:
《Java并发编程艺术》
《深入理解Java虚拟机》

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容