volatile 理解
- volatile是Java虛擬機裏面的輕量級的同步機制
- 保證可見性
- 不保證原子性
- 禁止指令重排序
Java 內存模型
Java虛擬機的規範中定義了什麼是Java內存模型(Java Memory Model,JMM)數據庫
Java內存模型自己是一種抽象的概念,也並不實體存在,它描述的是一組規則或者規範,經過這組鬼覅按,定義了程序中各個變量(包括實力字段,靜態字段和構成素組對象的元素)的訪問方式。它是用於屏蔽掉各類硬件與操做系統內存之間的訪問差別,從而實現讓Java程序在各類平臺下均可以作到同樣的運行效果,Java內存模型規範了Java虛擬機與計算機內存是如何協同工做,規定了一個線程應該如何以及何時能夠看到其餘線程修改後的共享變量的數據,以及如何同步訪問共享變量。舊版本的Java內存模型並不完善,所以Java內存模型在Java 1.5時被從新修訂。如今使用的Java 1.8也仍舊沿用着1.5的內存模型。併發
JMM關於同步的規定:spa
- 線程解鎖前,必須把共享變量的值刷新到主內存
- 線程加鎖前,必須讀取主內存的最新的值到工做內存
- 加鎖解鎖是同一把鎖
介於JVM運行程序的是基於線程的,且每一個線程都會擁有本身的一個工做內存,工做內存就是當前線程的私有數據空間,其餘線程不可訪問,而Java內存模型中同時規定全部數據都必須存儲在主內存,主內存是公共的內存區域,全部的線程均可以訪問,但線程對數據的讀取,賦值等必須在各自的工做內存中進行。不能夠直接操做主內存。所以,首先須要將數據從主內存複製到本身的工做內存,而後對數據進行操做,操做完成後再將新數據寫回主內存,不能直接操做主內存中的變量,各個線程中的工做內存中存儲着主內存的數據副本,所以不一樣的線程件沒法訪問其餘線程的工做內存,線程間的通訊必須經過主內存來完成。操作系統
Java內存模型是圍繞着在併發過程當中如何處理原子性、可見性和有序性這三個特徵來創建的。線程
- 原子性:對數據的操做是具有原子性的。有點像數據庫中的事務。讀取,修改,寫入時一鼓作氣,不可分割。synchronized代碼塊的操做也時原子性的。
- 可見性:Java內存模型是經過在數據修改後將新數據同步回主內存,當一個線程修改後,是否會通知其餘線程該數據已修改,導致其餘線程在操做前會從主內存從新刷新數據值的過程稱之爲可見性。除了volatile以外,synchronized和final關鍵字也實現了可見性。final修飾的字段在構造器中一旦初始化完成,那在其餘線程中就能看到final字段的值。
- 有序性:線程內表現爲串行的語義,不一樣線程之間存在指令重排序,即兩個不相關的變量賦值的前後順序並不影響單線程的運算結果,從而編譯器會對操做的變量進行從新排序。Java中提供了volatile和synchronized兩個關鍵字來保證線程之間操做的有序性。