volatile關(guān)鍵字有什么作用(變量可見性、禁止重排序)
1. volatile簡介
Java 語言提供了一種稍弱的同步機(jī)制,即 volatile 變量,用來確保將變量的更新操作通知到其他線程。volatile 變量具備兩種特性,volatile 變量不會被緩存在寄存器或者對其他處理器不可見的地方,因此在讀取 volatile 類型的變量時總會返回最新寫入的值。
變量可見性其一是保證該變量對所有線程可見,這里的可見性指的是當(dāng)一個線程修改了變量的值,那么新的值對于其他線程是可以立即獲取的。
2. 禁止重排序
volatile 禁止了指令重排。它是一種比*sychronized* 更輕量級的同步鎖。
我們在訪問 volatile 變量時不會執(zhí)行加鎖操作,因此也就不會使執(zhí)行線程阻塞,因此 volatile 變量是一種比 sychronized 關(guān)鍵字更輕量級的同步機(jī)制。volatile 適合這種場景:一個變量被多個線程共享,線程直接給這個變量賦值。
當(dāng)對非 volatile 變量進(jìn)行讀寫的時候,每個線程先從內(nèi)存拷貝變量到 CPU 緩存中。如果計(jì)算機(jī)有多個 CPU,每個線程可能在不同的 CPU 上被處理,這意味著每個線程可以拷貝到不同的 CPU cache 中。而聲明變量是 volatile 的,JVM 保證了每次讀變量都從內(nèi)存中讀,跳過 CPU cache 這一步。
適用場景值得說明的是對 volatile 變量的單次讀/寫操作可以保證原子性的,如 long 和 double 類型變量,但是并不能保證 i++這種操作的原子性,因?yàn)楸举|(zhì)上 i++是讀、寫兩次操作。在某些場景下可以代替 Synchronized。但是,volatile 的不能完全取代 Synchronized 的位置,只有在一些特殊的場景下,才能適用 volatile??偟膩碚f,必須同時滿足下面兩個條件才能保證在并發(fā)環(huán)境的線程安全:
對變量的寫操作不依賴于當(dāng)前值(比如 i++),或者說是單純的變量賦值(boolean flag = true)。
該變量沒有包含在具有其他變量的不變式中,也就是說,不同的 volatile 變量之間,不能互相依賴。只有在狀態(tài)真正獨(dú)立于程序內(nèi)其他內(nèi)容時才能使用 volatile。
更多關(guān)于“Java培訓(xùn)”的問題,歡迎咨詢千鋒教育在線名師。千鋒已有十余年的培訓(xùn)經(jīng)驗(yàn),課程大綱更科學(xué)更專業(yè),有針對零基礎(chǔ)的就業(yè)班,有針對想提升技術(shù)的好程序員班,高品質(zhì)課程助力你實(shí)現(xiàn)java程序員夢想。