1. 程式人生 > >【死磕Java併發】-----Java記憶體模型之總結

【死磕Java併發】-----Java記憶體模型之總結

經過四篇部落格闡述,我相信各位對Java記憶體模型有了最基本認識了,下面LZ就做一個比較簡單的總結。

總結

JMM規定了執行緒的工作記憶體和主記憶體的互動關係,以及執行緒之間的可見性和程式的執行順序。一方面,要為程式設計師提供足夠強的記憶體可見性保證;另一方面,對編譯器和處理器的限制要儘可能地放鬆。JMM對程式設計師遮蔽了CPU以及OS記憶體的使用問題,能夠使程式在不同的CPU和OS記憶體上都能夠達到預期的效果。

Java採用記憶體共享的模式來實現執行緒之間的通訊。編譯器和處理器可以對程式進行重排序優化處理,但是需要遵守一些規則,不能隨意重排序。

原子性:一個操作或者多個操作要麼全部執行要麼全部不執行;

可見性:當多個執行緒同時訪問一個共享變數時,如果其中某個執行緒更改了該共享變數,其他執行緒應該可以立刻看到這個改變;

有序性:程式的執行要按照程式碼的先後順序執行;

在併發程式設計模式中,勢必會遇到上面三個概念,JMM對原子性並沒有提供確切的解決方案,但是JMM解決了可見性和有序性,至於原子性則需要通過鎖或者Synchronized來解決了。

如果一個操作A的操作結果需要對操作B可見,那麼我們就認為操作A和操作B之間存在happens-before關係,即A happens-before B。

happens-before原則是JMM中非常重要的一個原則,它是判斷資料是否存在競爭、執行緒是否安全的主要依據,依靠這個原則,我們可以解決在併發環境下兩個操作之間是否存在衝突的所有問題。JMM規定,兩個操作存在happens-before關係並不一定要A操作先於B操作執行,只要A操作的結果對B操作可見即可。

在程式執行過程中,為了執行的效率,編譯器和處理器是可以對程式進行一定的重排序,但是他們必須要滿足兩個條件:1 執行的結果保持不變,2 存在資料依賴的不能重排序。重排序是引起多執行緒不安全的一個重要因素。

同時順序一致性是一個比較理想化的參考模型,它為我們提供了強大而又有力的記憶體可見性保證,他主要有兩個特徵:1 一個執行緒中的所有操作必須按照程式的順序來執行;2 所有執行緒都只能看到一個單一的操作執行順序,在順序一致性模型中,每個操作都必須原則執行且立刻對所有執行緒可見。

博文列表

Java記憶體模型推薦資料

歡迎掃一掃我的公眾號關注 — 及時得到部落格訂閱哦!

–— Java成神之路: 488391811(一起走向Java成神) –—
這裡寫圖片描述

相關推薦

Java併發-----Java記憶體模型happens-before

在上篇部落格(【死磕Java併發】—–深入分析volatile的實現原理)LZ提到過由於存線上程本地記憶體和主記憶體的原因,再加上重排序,會導致多執行緒環境下存在可見性的問題。那麼我們正確使用同步、鎖的情況下,執行緒A修改了變數a何時對執行緒B可見? 我們無法就所有場景來規

Java併發-----Java記憶體模型分析volatile

volatile可見性;對一個volatile的讀,總可以看到對這個變數最終的寫; volatile原子性;volatile對單個讀/寫具有原子性(32位Long、Double),但是複合操作除外,例如i++; JVM底層採用“記憶體屏障”來實現volat

Java併發--Java記憶體模型happens-before

在上篇部落格(【死磕Java併發】—–深入分析volatile的實現原理)LZ提到過由於存線上程本地記憶體和主記憶體的原因,再加上重排序,會導致多執行緒環境下存在可見性的問題。那麼我們正確使用同步、鎖的情況下,執行緒A修改了變數a何時對執行緒B可見?我們無法就所有場景來規定某

Java併發-----Java記憶體模型總結

經過四篇部落格闡述,我相信各位對Java記憶體模型有了最基本認識了,下面LZ就做一個比較簡單的總結。 總結 JMM規定了執行緒的工作記憶體和主記憶體的互動關係,以及執行緒之間的可見性和程式的執行順序。一方面,要為程式設計師提供足夠強的記憶體可見性保證;另

Java併發-----J.U.CAQS:阻塞和喚醒執行緒

此篇部落格所有原始碼均來自JDK 1.8 線上程獲取同步狀態時如果獲取失敗,則加入CLH同步佇列,通過通過自旋的方式不斷獲取同步狀態,但是在自旋的過程中則需要判斷當前執行緒是否需要阻塞,其主要方法在acquireQueued(): if (sho

Java併發-----J.U.C阻塞佇列:ArrayBlockingQueue

ArrayBlockingQueue,一個由陣列實現的有界阻塞佇列。該佇列採用FIFO的原則對元素進行排序新增的。 ArrayBlockingQueue為有界且固定,其大小在構造時由建構函式來決定,確認之後就不能再改變了。ArrayBlockingQueu

Java併發—– J.U.C併發工具類:Semaphore

此篇部落格所有原始碼均來自JDK 1.8訊號量Semaphore是一個控制訪問多個共享資源的計數

Java併發—– J.U.CAQS:同步狀態的獲取與釋放

此篇部落格所有原始碼均來自JDK 1.8在前面提到過,AQS是構建Java同步元件的基礎,我們期

Java併發-----J.U.C併發工具類:Exchanger

此篇部落格所有原始碼均來自JDK 1.8 前面三篇部落格分別介紹了CyclicBarrier、CountDownLatch、Semaphore,現在介紹併發工具類中的最後一個Exchange。Exchange是最簡單的也是最複雜的,簡單在於API非常簡

Java併發-----J.U.CCondition

此篇部落格所有原始碼均來自JDK 1.8 在沒有Lock之前,我們使用synchronized來控制同步,配合Object的wait()、notify()系列方法可以實現等待/通知模式。在Java SE5後,Java提供了Lock介面,相對於Synch

Java併發-----J.U.C重入鎖:ReentrantLock

此篇部落格所有原始碼均來自JDK 1.8 ReentrantLock,可重入鎖,是一種遞迴無阻塞的同步機制。它可以等同於synchronized的使用,但是ReentrantLock提供了比synchronized更強大、靈活的鎖機制,可以減少死鎖發生

Java併發-----J.U.C阻塞佇列:DelayQueue

DelayQueue是一個支援延時獲取元素的無界阻塞佇列。裡面的元素全部都是“可延期”的元素,列頭的元素是最先“到期”的元素,如果佇列裡面沒有元素到期,是不能從列頭獲取元素的,哪怕有元素也不行。也就是說只有在延遲期到時才能夠從佇列中取元素。 DelayQu

Java併發-----J.U.C併發工具類:CyclicBarrier

此篇部落格所有原始碼均來自JDK 1.8 CyclicBarrier,一個同步輔助類,在API中是這麼介紹的: 它允許一組執行緒互相等待,直到到達某個公共屏障點 (common barrier point)。在涉及一組固定大小的執行緒的程式中,這些執

Java併發—–J.U.CAQS(一篇就夠了)

作者:大明哥  原文地址:http://cmsblogs.com 越是核心的東西越是要反覆看,本文篇幅較長,希望各位細細品讀,來回多讀幾遍理解下。 AQS簡介 java的內建鎖一直都是備受爭議的,在JDK 1.6之前,synchronized這個重量級鎖其效能一直都

Java併發-----J.U.CAQS:AQS簡介

Java的內建鎖一直都是備受爭議的,在JDK 1.6之前,synchronized這個重量級鎖其效能一直都是較為低下,雖然在1.6後,進行大量的鎖優化策略(【死磕Java併發】—–深入分析synchronized的實現原理),但是與Lock相比synchroni

Java併發-----J.U.CAQS:CLH同步佇列

此篇部落格所有原始碼均來自JDK 1.8 CLH同步佇列是一個FIFO雙向佇列,AQS依賴它來完成同步狀態的管理,當前執行緒如果獲取同步狀態失敗時,AQS則會將當前執行緒已經等待狀態等資訊構造成一個節點(Node)並將其加入到CLH同步佇列,同時會

Java併發Java中的原子操作

Java中的原子操作 原子更新基本型別 原子更新陣列 原子更新引用型別 原子更新欄位類 參考 原子更新基本型別 一個生動的例子 public class AtomicIntegerExample { privat

Java併發Java中的執行緒池

Java中的執行緒池 執行流程 執行緒池的建立 提交任務 關閉執行緒池 參考 執行流程 處理流程如下: execute()方法執行示意圖如下: 執行緒池的建立 corePoolSize:執行緒池

springboot2.0springboot基於web開發

宣告,使用 maven3.5.4,springboot2.0,JDK8 ,idea2018.2 模組目錄結構: main 主方法: @SpringBootApplication public class WebApplication { public static voi

springboot2.0@restcontroller與 @controller的 區別;

@restcontroller *原始碼如下:其包含@Controller 、@ResponseBody * @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Controller