JMM(Java內存模型)主要有三大特性:原子性,可見性和有序性,今天咱們就來了解一下這三大特性。編程
原子性
- 原子性是指一個操做是不能夠中斷的。即便是多個線程一塊兒執行的狀況下也同樣,這個操做操做一旦開始就不會被其餘因素鎖影響(除了JVM退出等等的狀況)。
- 須要注意的是,什麼操做才能算是原子操做呢?像:int i = 1;這類語句就能夠稱爲原子語句。那麼i++ 能不能算是一條原子操做的語句呢?這乍一看像是一條語句,但實際它是兩條語句:第一步先將i進行加1的操做,第二步再將新的值賦值與i,因此i++不是一條原子操做的語句。
可見性
- 可見性指的是在併發編程的時候,一個線程修改了某一個共享變量的值,其它線程是否能當即察覺到這個變量值發生了改變。(在串行的狀況下,可見性問題是不存在的,由於在串行程序改變值之後,後面讀取的都是這個修改後的值)
有序性
- 在串行編程的狀況下,代碼通常都是從上往下依次執行的。可是在併發編程的狀況下,可能進行指令重排的狀況,寫在前面的代碼會在後面執行。
- 既然可能發生指令重排的狀況,那就是有些狀況下不會發生重排,不會發生重排涉及到一個原則,Happen-Before原則:
- 程序順序原則:一個線程內保證語義的串行性。
- volatile原則:volatile變量的寫,先發生於讀,這就保證了volatile的可見性
- 解鎖(unlock)發生在隨後的解鎖(lock)前
- 傳遞性:A先於B,B先於C,那麼A先於C
- 線程的start先於它的一切操做
- 線程的操做先於線程的終結
- 線程的終端先於被中斷的代碼
- 對象的改造函數執行、結束先於finalize()前