Java內存模型的核心問題就是如何解決一致性問題?
java內存模型其實是跟計算機硬件發展息息相關的,CPU的運算能力相比較于硬盤,內存的存取能力是相當高的,就好比我(CPU)分明能一分鐘從1加到100,你(內存)卻只能給到我1到10,內存的存取大大的限制了CPU的運算,所以就在內存和CPU中間加了高速緩存,用于CPU的快速計算,如下圖:
JAVA內存模型也采用了相似的結構,線程與CPU交互的時候,為了快速的進行運算,線程本地會開辟一份內存用于數據存儲,然后快速的與CPU進行交互,CPU的運算數據也通過線程推送到內存中,如下圖:
現在問題來了,從CPU到主內存需要經過線程的本地內存,在多線程的環境下,如果CPU運算數據不能及時的推到主內存中,就引發了線程安全問題,比如java中的經典案例i=0;i++;這么一個簡單地語句,如果線程1將i變為1之后還沒來得及寫到主內存中,線程2也是用i=0這個數據去運算,那么原本i++兩次之后應該得到2,現在卻只能輸出1;
由此可見java內存模型是模擬計算機硬件設計的,主要的作用其實還是用來提升整個系統的運算能力,但卻由此產生了多線程的線程安全問題,線程安全的主要問題是原子性,可見性,有序性問題;
怎么解決線程安全的問題呢?
1,資源不共享:比如TheadLocal,數據直接放在線程的本地內存中,每個線程有一份自己的數據,不存在安全問題
2,資源共享但是加鎖:比如synchronize,reentrantLock等,將共享資源進行加鎖,只有在保證線程處理完成或者中斷的時候,才會讓別的線程繼續處理這份數據;
3,資源共享但是無鎖:比如AtomicBoolean,AtomicInteger等主要是使用CAS保證數據的原子性操作,使用volatile保證數據的可見性來保證數據安全;
本文提到的東西比較淺顯易懂,更多深入的,精彩的java方面的技術分享正在路上,需要的朋友敬請關注。。。