【轉(zhuǎn)】Java內(nèi)存模型

本文來(lái)自Hollis [Hollis]的微信公眾號(hào)

前幾天,發(fā)了一篇文章漠烧,介紹了一下JVM內(nèi)存結(jié)構(gòu)梆掸、Java內(nèi)存模型以及Java對(duì)象模型之間的區(qū)別痴脾。有很多小伙伴反饋希望可以深入的講解下每個(gè)知識(shí)點(diǎn)纪挎。Java內(nèi)存模型期贫,是這三個(gè)知識(shí)點(diǎn)當(dāng)中最晦澀難懂的一個(gè),而且涉及到很多背景知識(shí)和相關(guān)知識(shí)异袄。

網(wǎng)上有很多關(guān)于Java內(nèi)存模型的文章通砍,在《深入理解Java虛擬機(jī)》和《Java并發(fā)編程的藝術(shù)》等書中也都有關(guān)于這個(gè)知識(shí)點(diǎn)的介紹。但是烤蜕,很多人讀完之后還是搞不清楚封孙,甚至有的人說(shuō)自己更懵了。本文讽营,就來(lái)整體的介紹一下Java內(nèi)存模型虎忌,目的很簡(jiǎn)單,讓你讀完本文以后斑匪,就知道到底Java內(nèi)存模型是什么呐籽,為什么要有Java內(nèi)存模型,Java內(nèi)存模型解決了什么問(wèn)題等蚀瘸。

本文中狡蝶,有很多定義和說(shuō)法,都是筆者自己理解后定義出來(lái)的贮勃。希望能夠讓讀者可以對(duì)Java內(nèi)存模型有更加清晰的認(rèn)識(shí)贪惹。當(dāng)然,如有偏頗寂嘉,歡迎指正奏瞬。

為什么要有內(nèi)存模型

在介紹Java內(nèi)存模型之前,先來(lái)看一下到底什么是計(jì)算機(jī)內(nèi)存模型泉孩,然后再來(lái)看Java內(nèi)存模型在計(jì)算機(jī)內(nèi)存模型的基礎(chǔ)上做了哪些事情硼端。要說(shuō)計(jì)算機(jī)的內(nèi)存模型,就要說(shuō)一下一段古老的歷史寓搬,看一下為什么要有內(nèi)存模型珍昨。

內(nèi)存模型,英文名Memory Model句喷,他是一個(gè)很老的老古董了镣典。他是與計(jì)算機(jī)硬件有關(guān)的一個(gè)概念。那么我先給你介紹下他和硬件到底有啥關(guān)系唾琼。

CPU和緩存一致性

我們應(yīng)該都知道兄春,計(jì)算機(jī)在執(zhí)行程序的時(shí)候,每條指令都是在CPU中執(zhí)行的锡溯,而執(zhí)行的時(shí)候赶舆,又免不了要和數(shù)據(jù)打交道。而計(jì)算機(jī)上面的數(shù)據(jù)祭饭,是存放在主存當(dāng)中的涌乳,也就是計(jì)算機(jī)的物理內(nèi)存啦。

剛開始甜癞,還相安無(wú)事的夕晓,但是隨著CPU技術(shù)的發(fā)展,CPU的執(zhí)行速度越來(lái)越快悠咱。而由于內(nèi)存的技術(shù)并沒(méi)有太大的變化蒸辆,所以從內(nèi)存中讀取和寫入數(shù)據(jù)的過(guò)程和CPU的執(zhí)行速度比起來(lái)差距就會(huì)越來(lái)越大,這就導(dǎo)致CPU每次操作內(nèi)存都要耗費(fèi)很多等待時(shí)間。

這就像一家創(chuàng)業(yè)公司析既,剛開始躬贡,創(chuàng)始人和員工之間工作關(guān)系其樂(lè)融融,但是隨著創(chuàng)始人的能力和野心越來(lái)越大眼坏,逐漸和員工之間出現(xiàn)了差距拂玻,普通員工原來(lái)越跟不上CEO的腳步。老板的每一個(gè)命令,傳到到基層員工之后檐蚜,由于基層員工的理解能力魄懂、執(zhí)行能力的欠缺,就會(huì)耗費(fèi)很多時(shí)間闯第。這也就無(wú)形中拖慢了整家公司的工作效率市栗。

可是,不能因?yàn)閮?nèi)存的讀寫速度慢咳短,就不發(fā)展CPU技術(shù)了吧填帽,總不能讓內(nèi)存成為計(jì)算機(jī)處理的瓶頸吧。

所以咙好,人們想出來(lái)了一個(gè)好的辦法篡腌,就是在CPU和內(nèi)存之間增加高速緩存。緩存的概念大家都知道勾效,就是保存一份數(shù)據(jù)拷貝哀蘑。他的特點(diǎn)是速度快,內(nèi)存小葵第,并且昂貴绘迁。

那么,程序的執(zhí)行過(guò)程就變成了:

當(dāng)程序在運(yùn)行過(guò)程中卒密,會(huì)將運(yùn)算需要的數(shù)據(jù)從主存復(fù)制一份到CPU的高速緩存當(dāng)中缀台,那么CPU進(jìn)行計(jì)算時(shí)就可以直接從它的高速緩存讀取數(shù)據(jù)和向其中寫入數(shù)據(jù),當(dāng)運(yùn)算結(jié)束之后哮奇,再將高速緩存中的數(shù)據(jù)刷新到主存當(dāng)中膛腐。

之后,這家公司開始設(shè)立中層管理人員鼎俘,管理人員直接歸CEO領(lǐng)導(dǎo)哲身,領(lǐng)導(dǎo)有什么指示,直接告訴管理人員贸伐,然后就可以去做自己的事情了勘天。管理人員負(fù)責(zé)去協(xié)調(diào)底層員工的工作。因?yàn)楣芾砣藛T是了解手下的人員以及自己負(fù)責(zé)的事情的捉邢。所以脯丝,大多數(shù)時(shí)候,公司的各種決策伏伐,通知等宠进,CEO只要和管理人員之間溝通就夠了。

而隨著CPU能力的不斷提升藐翎,一層緩存就慢慢的無(wú)法滿足要求了材蹬,就逐漸的衍生出多級(jí)緩存实幕。

按照數(shù)據(jù)讀取順序和與CPU結(jié)合的緊密程度,CPU緩存可以分為一級(jí)緩存(L1)堤器,二級(jí)緩存(L3)昆庇,部分高端CPU還具有三級(jí)緩存(L3),每一級(jí)緩存中所儲(chǔ)存的全部數(shù)據(jù)都是下一級(jí)緩存的一部分吼旧。

這三種緩存的技術(shù)難度和制造成本是相對(duì)遞減的凰锡,所以其容量也是相對(duì)遞增的未舟。

那么圈暗,在有了多級(jí)緩存之后,程序的執(zhí)行就變成了:

當(dāng)CPU要讀取一個(gè)數(shù)據(jù)時(shí)裕膀,首先從一級(jí)緩存中查找员串,如果沒(méi)有找到再?gòu)亩?jí)緩存中查找,如果還是沒(méi)有就從三級(jí)緩存或內(nèi)存中查找昼扛。

隨著公司越來(lái)越大寸齐,老板要管的事情越來(lái)越多,公司的管理部門開始改革抄谐,開始出現(xiàn)高層渺鹦,中層,底層等管理者蛹含。一級(jí)一級(jí)之間逐層管理毅厚。

單核CPU只含有一套L1,L2浦箱,L3緩存吸耿;

如果CPU含有多個(gè)核心,即多核CPU酷窥,則每個(gè)核心都含有一套L1(甚至和L2)緩存咽安,而共享L3(或者和L2)緩存。

公司也分很多種蓬推,有些公司只有一個(gè)大Boss妆棒,他一個(gè)人說(shuō)了算。但是有些公司有比如聯(lián)席總經(jīng)理沸伏、合伙人等機(jī)制募逞。

單核CPU就像一家公司只有一個(gè)老板,所有命令都來(lái)自于他馋评,那么就只需要一套管理班底就夠了放接。

多核CPU就像一家公司是由多個(gè)合伙人共同創(chuàng)辦的,那么留特,就需要給每個(gè)合伙人都設(shè)立一套供自己直接領(lǐng)導(dǎo)的高層管理人員纠脾,多個(gè)合伙人共享使用的是公司的底層員工玛瘸。

還有的公司,不斷壯大苟蹈,開始差分出各個(gè)子公司糊渊。各個(gè)子公司就是多個(gè)CPU了,互相之前沒(méi)有共用的資源慧脱∶烊蓿互不影響。

下圖為一個(gè)單CPU雙核的緩存結(jié)構(gòu)菱鸥。

image

隨著計(jì)算機(jī)能力不斷提升宗兼,開始支持多線程。那么問(wèn)題就來(lái)了氮采。我們分別來(lái)分析下單線程殷绍、多線程在單核CPU、多核CPU中的影響鹊漠。

單線程主到。cpu核心的緩存只被一個(gè)線程訪問(wèn)。緩存獨(dú)占躯概,不會(huì)出現(xiàn)訪問(wèn)沖突等問(wèn)題登钥。

單核CPU,多線程娶靡。進(jìn)程中的多個(gè)線程會(huì)同時(shí)訪問(wèn)進(jìn)程中的共享數(shù)據(jù)牧牢,CPU將某塊內(nèi)存加載到緩存后,不同線程在訪問(wèn)相同的物理地址的時(shí)候固蛾,都會(huì)映射到相同的緩存位置结执,這樣即使發(fā)生線程的切換,緩存仍然不會(huì)失效艾凯。但由于任何時(shí)刻只能有一個(gè)線程在執(zhí)行献幔,因此不會(huì)出現(xiàn)緩存訪問(wèn)沖突。

多核CPU趾诗,多線程蜡感。每個(gè)核都至少有一個(gè)L1 緩存。多個(gè)線程訪問(wèn)進(jìn)程中的某個(gè)共享內(nèi)存恃泪,且這多個(gè)線程分別在不同的核心上執(zhí)行郑兴,則每個(gè)核心都會(huì)在各自的cache中保留一份共享內(nèi)存的緩沖。由于多核是可以并行的贝乎,可能會(huì)出現(xiàn)多個(gè)線程同時(shí)寫各自的緩存的情況情连,而各自的cache之間的數(shù)據(jù)就有可能不同。

在CPU和主存之間增加緩存览效,在多線程場(chǎng)景下就可能存在緩存一致性問(wèn)題却舀,也就是說(shuō)虫几,在多核CPU中,每個(gè)核的自己的緩存中挽拔,關(guān)于同一個(gè)數(shù)據(jù)的緩存內(nèi)容可能不一致辆脸。

如果這家公司的命令都是串行下發(fā)的話,那么就沒(méi)有任何問(wèn)題螃诅。

如果這家公司的命令都是并行下發(fā)的話啡氢,并且這些命令都是由同一個(gè)CEO下發(fā)的,這種機(jī)制是也沒(méi)有什么問(wèn)題术裸。因?yàn)樗拿顖?zhí)行者只有一套管理體系倘是。

如果這家公司的命令都是并行下發(fā)的話,并且這些命令是由多個(gè)合伙人下發(fā)的穗椅,這就有問(wèn)題了辨绊。因?yàn)槊總€(gè)合伙人只會(huì)把命令下達(dá)給自己直屬的管理人員奶栖,而多個(gè)管理人員管理的底層員工可能是公用的匹表。

比如,合伙人1要辭退員工a宣鄙,合伙人2要給員工a升職袍镀,升職后的話他再被辭退需要多個(gè)合伙人開會(huì)決議。兩個(gè)合伙人分別把命令下發(fā)給了自己的管理人員冻晤。合伙人1命令下達(dá)后苇羡,管理人員a在辭退了員工后,他就知道這個(gè)員工被開除了鼻弧。而合伙人2的管理人員2這時(shí)候在沒(méi)得到消息之前设江,還認(rèn)為員工a是在職的,他就欣然的接收了合伙人給他的升職a的命令攘轩。


image

處理器優(yōu)化和指令重排

上面提到在在CPU和主存之間增加緩存叉存,在多線程場(chǎng)景下會(huì)存在緩存一致性問(wèn)題。除了這種情況度帮,還有一種硬件問(wèn)題也比較重要歼捏。那就是為了使處理器內(nèi)部的運(yùn)算單元能夠盡量的被充分利用,處理器可能會(huì)對(duì)輸入代碼進(jìn)行亂序執(zhí)行處理笨篷。這就是處理器優(yōu)化瞳秽。

除了現(xiàn)在很多流行的處理器會(huì)對(duì)代碼進(jìn)行優(yōu)化亂序處理,很多編程語(yǔ)言的編譯器也會(huì)有類似的優(yōu)化率翅,比如Java虛擬機(jī)的即時(shí)編譯器(JIT)也會(huì)做指令重排练俐。

可想而知,如果任由處理器優(yōu)化和編譯器對(duì)指令重排的話冕臭,就可能導(dǎo)致各種各樣的問(wèn)題腺晾。

關(guān)于員工組織調(diào)整的情況瓢棒,如果允許人事部在接到多個(gè)命令后進(jìn)行隨意拆分亂序執(zhí)行或者重排的話,那么對(duì)于這個(gè)員工以及這家公司的影響是非常大的丘喻。

并發(fā)編程的問(wèn)題

前面說(shuō)的和硬件有關(guān)的概念你可能聽(tīng)得有點(diǎn)蒙脯宿,還不知道他到底和軟件有啥關(guān)系。但是關(guān)于并發(fā)編程的問(wèn)題你應(yīng)該有所了解泉粉,比如原子性問(wèn)題连霉,可見(jiàn)性問(wèn)題和有序性問(wèn)題。

其實(shí)嗡靡,原子性問(wèn)題跺撼,可見(jiàn)性問(wèn)題和有序性問(wèn)題。是人們抽象定義出來(lái)的讨彼。而這個(gè)抽象的底層問(wèn)題就是前面提到的緩存一致性問(wèn)題歉井、處理器優(yōu)化問(wèn)題和指令重排問(wèn)題等。

這里簡(jiǎn)單回顧下這三個(gè)問(wèn)題哈误,并不準(zhǔn)備深入展開哩至,感興趣的讀者可以自行學(xué)習(xí)。我們說(shuō)蜜自,并發(fā)編程菩貌,為了保證數(shù)據(jù)的安全,需要滿足以下三個(gè)特性:

原子性是指在一個(gè)操作中就是cpu不可以在中途暫停然后再調(diào)度重荠,既不被中斷操作箭阶,要不執(zhí)行完成,要不就不執(zhí)行戈鲁。

可見(jiàn)性是指當(dāng)多個(gè)線程訪問(wèn)同一個(gè)變量時(shí)仇参,一個(gè)線程修改了這個(gè)變量的值,其他線程能夠立即看得到修改的值婆殿。

有序性即程序執(zhí)行的順序按照代碼的先后順序執(zhí)行诈乒。

有沒(méi)有發(fā)現(xiàn),緩存一致性問(wèn)題其實(shí)就是可見(jiàn)性問(wèn)題鸣皂。而處理器優(yōu)化是可以導(dǎo)致原子性問(wèn)題的抓谴。指令重排即會(huì)導(dǎo)致有序性問(wèn)題。所以寞缝,后文將不再提起硬件層面的那些概念癌压,而是直接使用大家熟悉的原子性、可見(jiàn)性和有序性荆陆。

什么是內(nèi)存模型

前面提到的滩届,緩存一致性問(wèn)題、處理器器優(yōu)化的指令重排問(wèn)題是硬件的不斷升級(jí)導(dǎo)致的被啼。那么帜消,有沒(méi)有什么機(jī)制可以很好的解決上面的這些問(wèn)題呢棠枉?

最簡(jiǎn)單直接的做法就是廢除處理器和處理器的優(yōu)化技術(shù)、廢除CPU緩存泡挺,讓CPU直接和主存交互辈讶。但是,這么做雖然可以保證多線程下的并發(fā)問(wèn)題娄猫。但是贱除,這就有點(diǎn)因噎廢食了。

所以媳溺,為了保證并發(fā)編程中可以滿足原子性月幌、可見(jiàn)性及有序性。有一個(gè)重要的概念悬蔽,那就是——內(nèi)存模型扯躺。

為了保證共享內(nèi)存的正確性(可見(jiàn)性、有序性蝎困、原子性)录语,內(nèi)存模型定義了共享內(nèi)存系統(tǒng)中多線程程序讀寫操作行為的規(guī)范。通過(guò)這些規(guī)則來(lái)規(guī)范對(duì)內(nèi)存的讀寫操作难衰,從而保證指令執(zhí)行的正確性钦无。它與處理器有關(guān)逗栽、與緩存有關(guān)盖袭、與并發(fā)有關(guān)、與編譯器也有關(guān)彼宠。他解決了CPU多級(jí)緩存鳄虱、處理器優(yōu)化、指令重排等導(dǎo)致的內(nèi)存訪問(wèn)問(wèn)題凭峡,保證了并發(fā)場(chǎng)景下的一致性拙已、原子性和有序性。

內(nèi)存模型解決并發(fā)問(wèn)題主要采用兩種方式:限制處理器優(yōu)化使用內(nèi)存屏障摧冀。本文就不深入底層原理來(lái)展開介紹了倍踪,感興趣的朋友可以自行學(xué)習(xí)。

什么是Java內(nèi)存模型

前面介紹過(guò)了計(jì)算機(jī)內(nèi)存模型索昂,這是解決多線程場(chǎng)景下并發(fā)問(wèn)題的一個(gè)重要規(guī)范建车。那么具體的實(shí)現(xiàn)是如何的呢,不同的編程語(yǔ)言椒惨,在實(shí)現(xiàn)上可能有所不同缤至。

我們知道,Java程序是需要運(yùn)行在Java虛擬機(jī)上面的康谆,Java內(nèi)存模型(Java Memory Model ,JMM)就是一種符合內(nèi)存模型規(guī)范的领斥,屏蔽了各種硬件和操作系統(tǒng)的訪問(wèn)差異的嫉到,保證了Java程序在各種平臺(tái)下對(duì)內(nèi)存的訪問(wèn)都能保證效果一致的機(jī)制及規(guī)范。

提到Java內(nèi)存模型月洛,一般指的是JDK 5 開始使用的新的內(nèi)存模型何恶,主要由JSR-133: JavaTM Memory Model and Thread Specification 描述。感興趣的可以參看下這份PDF文檔(http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf

Java內(nèi)存模型規(guī)定了所有的變量都存儲(chǔ)在主內(nèi)存中嚼黔,每條線程還有自己的工作內(nèi)存导而,線程的工作內(nèi)存中保存了該線程中是用到的變量的主內(nèi)存副本拷貝,線程對(duì)變量的所有操作都必須在工作內(nèi)存中進(jìn)行隔崎,而不能直接讀寫主內(nèi)存今艺。不同的線程之間也無(wú)法直接訪問(wèn)對(duì)方工作內(nèi)存中的變量,線程間變量的傳遞均需要自己的工作內(nèi)存和主存之間進(jìn)行數(shù)據(jù)同步進(jìn)行爵卒。

而JMM就作用于工作內(nèi)存和主存之間數(shù)據(jù)同步過(guò)程虚缎。他規(guī)定了如何做數(shù)據(jù)同步以及什么時(shí)候做數(shù)據(jù)同步。

image

這里面提到的主內(nèi)存和工作內(nèi)存钓株,讀者可以簡(jiǎn)單的類比成計(jì)算機(jī)內(nèi)存模型中的主存和緩存的概念实牡。特別需要注意的是,主內(nèi)存和工作內(nèi)存與JVM內(nèi)存結(jié)構(gòu)中的Java堆轴合、棧创坞、方法區(qū)等并不是同一個(gè)層次的內(nèi)存劃分,無(wú)法直接類比受葛√庹牵《深入理解Java虛擬機(jī)》中認(rèn)為,如果一定要勉強(qiáng)對(duì)應(yīng)起來(lái)的話总滩,從變量纲堵、主內(nèi)存、工作內(nèi)存的定義來(lái)看闰渔,主內(nèi)存主要對(duì)應(yīng)于Java堆中的對(duì)象實(shí)例數(shù)據(jù)部分席函。工作內(nèi)存則對(duì)應(yīng)于虛擬機(jī)棧中的部分區(qū)域。

所以冈涧,再來(lái)總結(jié)下茂附,JMM是一種規(guī)范,目的是解決由于多線程通過(guò)共享內(nèi)存進(jìn)行通信時(shí)督弓,存在的本地內(nèi)存數(shù)據(jù)不一致营曼、編譯器會(huì)對(duì)代碼指令重排序、處理器會(huì)對(duì)代碼亂序執(zhí)行等帶來(lái)的問(wèn)題咽筋。目的是保證并發(fā)編程場(chǎng)景中的原子性溶推、可見(jiàn)性和有序性。

Java內(nèi)存模型的實(shí)現(xiàn)

了解Java多線程的朋友都知道,在Java中提供了一系列和并發(fā)處理相關(guān)的關(guān)鍵字蒜危,比如volatile虱痕、synchronizedfinal辐赞、concurren包等部翘。其實(shí)這些就是Java內(nèi)存模型封裝了底層的實(shí)現(xiàn)后提供給程序員使用的一些關(guān)鍵字。

在開發(fā)多線程的代碼的時(shí)候响委,我們可以直接使用synchronized等關(guān)鍵字來(lái)控制并發(fā)新思,從來(lái)就不需要關(guān)心底層的編譯器優(yōu)化、緩存一致性等問(wèn)題赘风。所以夹囚,Java內(nèi)存模型,除了定義了一套規(guī)范邀窃,還提供了一系列原語(yǔ)荸哟,封裝了底層實(shí)現(xiàn)后,供開發(fā)者直接使用瞬捕。

本文并不準(zhǔn)備把所有的關(guān)鍵字逐一介紹其用法鞍历,因?yàn)殛P(guān)于各個(gè)關(guān)鍵字的用法,網(wǎng)上有很多資料肪虎。讀者可以自行學(xué)習(xí)劣砍。本文還有一個(gè)重點(diǎn)要介紹的就是,我們前面提到扇救,并發(fā)編程要解決原子性刑枝、有序性和一致性的問(wèn)題,我們就再來(lái)看下爵政,在Java中仅讽,分別使用什么方式來(lái)保證。

原子性

在Java中钾挟,為了保證原子性,提供了兩個(gè)高級(jí)的字節(jié)碼指令monitorentermonitorexit饱岸。在synchronized的實(shí)現(xiàn)原理文章中掺出,介紹過(guò),這兩個(gè)字節(jié)碼苫费,在Java中對(duì)應(yīng)的關(guān)鍵字就是synchronized汤锨。

因此,在Java中可以使用synchronized來(lái)保證方法和代碼塊內(nèi)的操作是原子性的百框。

可見(jiàn)性

Java內(nèi)存模型是通過(guò)在變量修改后將新值同步回主內(nèi)存闲礼,在變量讀取前從主內(nèi)存刷新變量值的這種依賴主內(nèi)存作為傳遞媒介的方式來(lái)實(shí)現(xiàn)的。

Java中的volatile關(guān)鍵字提供了一個(gè)功能,那就是被其修飾的變量在被修改后可以立即同步到主內(nèi)存柬泽,被其修飾的變量在每次是用之前都從主內(nèi)存刷新慎菲。因此,可以使用volatile來(lái)保證多線程操作時(shí)變量的可見(jiàn)性锨并。

除了volatile露该,Java中的synchronizedfinal兩個(gè)關(guān)鍵字也可以實(shí)現(xiàn)可見(jiàn)性。只不過(guò)實(shí)現(xiàn)方式不同第煮,這里不再展開了解幼。

有序性

在Java中,可以使用synchronizedvolatile來(lái)保證多線程之間操作的有序性包警。實(shí)現(xiàn)方式有所區(qū)別:

volatile關(guān)鍵字會(huì)禁止指令重排撵摆。synchronized關(guān)鍵字保證同一時(shí)刻只允許一條線程操作。

好了害晦,這里簡(jiǎn)單的介紹完了Java并發(fā)編程中解決原子性台汇、可見(jiàn)性以及有序性可以使用的關(guān)鍵字。讀者可能發(fā)現(xiàn)了篱瞎,好像synchronized關(guān)鍵字是萬(wàn)能的苟呐,他可以同時(shí)滿足以上三種特性,這其實(shí)也是很多人濫用synchronized的原因俐筋。

但是synchronized是比較影響性能的牵素,雖然編譯器提供了很多鎖優(yōu)化技術(shù),但是也不建議過(guò)度使用澄者。

總結(jié)

在讀完本文之后笆呆,相信你應(yīng)該了解了什么是Java內(nèi)存模型、Java內(nèi)存模型的作用以及Java中內(nèi)存模型做了什么事情等粱挡。

關(guān)于Java中這些和內(nèi)存模型有關(guān)的關(guān)鍵字赠幕,希望讀者還可以繼續(xù)深入學(xué)習(xí),并且自己寫幾個(gè)例子親自體會(huì)一下询筏¢叛撸可以參考《深入理解Java虛擬機(jī)》和《Java并發(fā)編程的藝術(shù)》兩本書。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嫌套,一起剝皮案震驚了整個(gè)濱河市逆屡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌踱讨,老刑警劉巖魏蔗,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異痹筛,居然都是意外死亡莺治,警方通過(guò)查閱死者的電腦和手機(jī)廓鞠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谣旁,“玉大人床佳,你說(shuō)我怎么就攤上這事÷冢” “怎么了夕土?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)瘟判。 經(jīng)常有香客問(wèn)我怨绣,道長(zhǎng),這世上最難降的妖魔是什么拷获? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任篮撑,我火速辦了婚禮,結(jié)果婚禮上匆瓜,老公的妹妹穿的比我還像新娘赢笨。我一直安慰自己,他們只是感情好驮吱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布茧妒。 她就那樣靜靜地躺著,像睡著了一般左冬。 火紅的嫁衣襯著肌膚如雪桐筏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天拇砰,我揣著相機(jī)與錄音梅忌,去河邊找鬼。 笑死除破,一個(gè)胖子當(dāng)著我的面吹牛牧氮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瑰枫,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼踱葛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了躁垛?” 一聲冷哼從身側(cè)響起剖毯,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎教馆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體擂达,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡土铺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年胶滋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悲敷。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡究恤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出后德,到底是詐尸還是另有隱情部宿,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布瓢湃,位于F島的核電站理张,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏绵患。R本人自食惡果不足惜雾叭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望落蝙。 院中可真熱鬧织狐,春花似錦、人聲如沸筏勒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)管行。三九已至厨埋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間病瞳,已是汗流浹背揽咕。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留套菜,地道東北人亲善。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像逗柴,于是被迫代替她去往敵國(guó)和親蛹头。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容