* Java內存模型是圍繞着在併發過程當中如何處理原子性、可見性、和有序性這3個特徵來創建的 * 原子性(Atomicity) * 一、由Java內存模型來直接保證的原子性變量操做包括read、load、assign、use、store和write, * 大體能夠認爲基本數據類型的訪問讀寫是具有原子性的(例外就是long和double的非原子性協定)。 * * 二、Java內存模型還提供了lock和unlock操做來知足這種需求,儘管虛擬機未把lock和unlock操做 * 直接開放給用戶使用,可是卻提供了更高層次的字節碼指令monitorenter和monitorexit來隱式地 * 使用這兩個操做,這個兩個字節碼指令反映到Java代碼中就是同步塊--synchronized關鍵字,所以 * 在synchronized塊之間的操做也具有原子性。 * 可見性(Visibility) * * 有序性(Ordering) * * * synchronized關鍵字說明 * 一、互斥同步(Mutual Exclusion & Synchronization)是常見的一種併發正確性保障手段。同步是指在多個線程併發訪問共享數據時, * 保證共享數據在同一個時刻只被一個(或者是一些,使用信號量的時候)線程使用。而互斥是實現同步的一種手段,臨界區(Critical Section)、 * 互斥量(Mutex)和信號量(Semaphore)都是主要的互斥實現方式。所以,在這4個字裏面,互斥是因,同步是果;互斥是方法,同步是目的。 * * 二、在Java中,最基本的互斥同步手段就是synchronized關鍵字,synchronized關鍵字通過編譯以後,會在同步塊的先後分別造成monitorenter * 和monitorexit這兩個字節碼指令,這兩個字節碼都須要一個reference類型的參數來指明要鎖定和解鎖的對象。若是Java程序中的synchronized * 明確指定了對象參數,那就是這個對象的reference;若是沒有明確指定,那就根據synchronized修飾的是實例方法仍是類方法,去取對應的 * 對象實例或Class對象來做爲鎖對象。 * * 三、根據虛擬機規範的要求,在執行monitorenter指令時,首先要嘗試獲取對象的鎖。若是這個對象沒被鎖定,或者當前線程已經擁有了那個對象的 * 鎖,把鎖的計數器加1,相應的,在執行monitorexit指令時會將鎖計數器減1,當計數器爲0時,鎖就被釋放。若是獲取對象鎖失敗,那當前線程就要 * 阻塞等待,直到對象鎖被另一個線程釋放爲止。 * * 四、synchronized同步塊對同一條線程來講是可重入的,不會出現本身把本身鎖死的問題。其次,同步塊在已進入的線程執行完以前,會阻塞後面 * 其它線程的進入。