volatile關鍵字的作用 1. 所有變數的可見性——僅僅是修改後的值的可見性,不保證併發修改時新值和預期一致。即只保證讀,不保證寫。 2. 禁止指令重排序——修飾的變數,讀寫不會指令重排。如變數isReady被volatile修飾,這兩條指令 和`isReady=true`不會在編譯時改變順序。 ...
volatile關鍵字的作用
- 所有變數的可見性——僅僅是修改後的值的可見性,不保證併發修改時新值和預期一致。即只保證讀,不保證寫。
- 禁止指令重排序——修飾的變數,讀寫不會指令重排。如變數isReady被volatile修飾,這兩條指令
int B = 0
和isReady=true
不會在編譯時改變順序。註意這裡是機器級代碼的重排序。
多線程的實現
JDK基於具體系統來做的,如內核線程、用戶線程、用戶線程加輕量進程混合等。
不可變
初始化後就不會改變
- final修飾
- String
- java.lang.Number的部分子類如Long、Double,AtomicInteger和AtomicLong除外
線程安全
如Vector這樣的容器,雖然get()、size()、add()等有synchronized關鍵字,但是實際使用時還是需要額外的同步(可以是針對容器對象本身的synchronized)保障。
原因是,Vector的線程安全,指的是其對應方法不可打斷。但是在多線程環境下,多個方法按順序執行時,仍有可能產生非預期的行為。
舉例:對於非空Vector,記為v,多個線程同時執行remove(v.size()-1)
,有可能發生數組越界。
逃逸分析
(實際是第11章的內容)
運行期優化,判斷一個對象是否會逃逸到方法外或其他線程。如果不會逃逸,對應的優化手段:
- 棧上分配,在棧上分配這個對象
- 同步消除,去掉這個對象多線程下的同步措施
- 標量替換,將這個對象拆分成標量(基本數據類型、referrence等)來創建而不是創建這個對象。