從面向?qū)ο笤O(shè)計(jì)的角度出發(fā)介紹幾種保障線程安全的設(shè)計(jì)技術(shù),這些技術(shù)可以使得我們?cè)诓槐亟柚i的情況下保障線程安全,避免鎖可能導(dǎo)致的問(wèn)題及開(kāi)銷(xiāo)。
Java運(yùn)行時(shí)(Java runtime)內(nèi)存可以分為棧區(qū),堆區(qū)與方法區(qū)(非堆空間)。
??臻g(Stack Space)為線程的執(zhí)行準(zhǔn)備一段固定大小的存儲(chǔ)空間,每個(gè)線程都有獨(dú)立的線程??臻g,創(chuàng)建線程時(shí)就為線程分配??臻g.在線程棧中每調(diào)用一個(gè)方法就給方法分配一個(gè)棧幀,棧幀用于存儲(chǔ)方法的局部變量,返回值等私有數(shù)據(jù), 即局部變量存儲(chǔ)在??臻g中, 基本類(lèi)型變量也是存儲(chǔ)在??臻g中, 引用類(lèi)型變量值也是存儲(chǔ)在棧空間中,引用 的對(duì)象存儲(chǔ)在堆中. 由于線程棧是相互獨(dú)立的,一個(gè)線程不能訪問(wèn)另外一個(gè)線程的??臻g,因此線程對(duì)局部變量以及只能通過(guò)當(dāng)前線程的局部變量才能訪問(wèn)的對(duì)象進(jìn)行的操作具有固定的線程安全性。
堆空間(Heap Space)用于存儲(chǔ)對(duì)象,是在JVM啟動(dòng)時(shí)分配的一段可以動(dòng)態(tài)擴(kuò)容的內(nèi)存空間. 創(chuàng)建對(duì)象時(shí),在堆空間中給對(duì)象分配存儲(chǔ)空間,實(shí)例變量就是存儲(chǔ)在堆空間中的, 堆空間是多個(gè)線程之間可以共享的空間,因此實(shí)例變量可以被多個(gè)線程共享. 多個(gè)線程同時(shí)操作實(shí)例變量可能存在線程安全問(wèn)題。
非堆空間(Non-Heap Space)用于存儲(chǔ)常量,類(lèi)的元數(shù)據(jù)等, 非堆空間也是在JVM啟動(dòng)時(shí)分配的一段可以動(dòng)態(tài)擴(kuò)容的存儲(chǔ)空間.類(lèi)的元數(shù)據(jù)包括靜態(tài)變量,類(lèi)有哪些方法及這些方法的元數(shù)據(jù)(方法名,參數(shù),返回值等). 非堆空間也是多個(gè) 線程可以共享的, 因此訪問(wèn)非堆空間中的靜態(tài)變量也可能存在線程安全問(wèn)題。
堆空間也非堆空間是線程可以共享的空間,即實(shí)例變量與靜態(tài)變量是線程可以共享的,可能存在線程安全問(wèn)題. ??臻g是線程私有的存儲(chǔ)空間,局部變量存儲(chǔ)在??臻g中,局部變量具有固定的線程安全性。