violate關鍵字的理解

要理解violate關鍵字,首先你必定要先對jvm運行內存有了解,咱們先來大體的瞭解一下jvm運行內存分區緩存

jvm運行是的內存分區主要有:安全

一、程序計數器二、jvm運行棧(這部分區域主要是存儲局部變量表,基本數據類型等)三、jvm堆內存(這裏主要是存儲對象的,也就是全部的new對象的實例都是在這裏,這裏是整個運行期間的共享內存,還有每一個線程的緩衝區)四、方法區(這裏是加載的類都會存在這裏,注意這裏是加載的類,不是實例對象,要區分和堆內存的區別)五、本地方法棧(主要是jvm在使用native方法的區域)六、運行時常量池(好比咱們的String string ="string",這種以雙引號修飾的會直接存儲到常量池中)七、直接內存。因此咱們能夠直接的認爲你寫的一個類裏面的代碼在jvm運行的時候都是會被分配到不一樣的內存中去的!
上面咱們已經瞭解了jvm的內存分區了,下面咱們來講說這個violate關鍵字。每一個線程在初始化的時候都會在堆內存上申請一個緩衝區,每一個緩衝區只能是對應的線程使用,當線程在使用主內存中的變量的時候,都會把主內存的值複製一份到本身的緩衝區,每一個線程都會從本身的緩衝區去讀取本身要是用的主內存中的值,這就致使了當一個線程改變了主內存的值,在會寫給主內存的時候這段時間其餘線程拿的來時原來的值,被violate修飾的變量,在被任意一個線程修改的時候,他就會強制性的讓其餘線程緩存的值無效,從而讓線程強制性的從新去主內存中讀取。因此每一個線程都能拿到主內存中最新的值,注意是最新的,他保證了變量對於其餘線程的可見性。------可見性併發

另外,Java在運行的時候會發生重排序,什麼是重排序,樓主目前理解的就是在不改變結果的狀況下,選擇最優的執行順序,例如:①int a = 1,②int b = 2;③int c = a+b;程序執行的順序有多是①②③,②①③,只有這兩種可能,爲何③會一直在最後呢,由於c的值依賴於a和b,若是③的順序發生了變化那就違背了重排序不會致使最後的結果發生改變。可是若是b用violate修飾了以後,順序只能是①②③,它明確告訴計算機禁止對所修飾的變量重排序!-----禁止重排序jvm

上面咱們說過,violate修飾的變量線程只能拿到最新的,並不能拿到最真的,在高併發的狀況下,當兩個線程同時修改主內存的值,那就會致使主內存的值不是最終的值,也就是說violate修飾的變量並不能保證原子性,因此對於violate修飾的變量咱們爲了保證原子性,仍是要加上同步鎖的!-----不是線程安全的高併發

相關文章
相關標籤/搜索