摘要:現(xiàn)在的處理器,一般是會(huì)有多個(gè)的,每個(gè)線程可能運(yùn)行在不同的,那么線程修改完成的值,是首先保存在中去。考慮這樣一種情況現(xiàn)在有兩個(gè)線程,線程和線程,他們不時(shí)會(huì)去讀取這個(gè)共享變量。
什么是volatile
關(guān)鍵字volatile 提供了Java 虛擬機(jī)中最輕量級(jí)的同步機(jī)制。在meidium 中有篇文章說(shuō):Volatile?specifier?is used to indicate that a?variable’s value can be modified by multiple?threads?simultaneously
當(dāng)你使用了volatile之后,那么這個(gè)變量會(huì)有如下的特性:
保證此變量對(duì)所有的線程的可見(jiàn)性
禁止指令重排序優(yōu)化
對(duì)于第一條的內(nèi)容,volatile是如何保證讀寫(xiě)操作對(duì)所有的線程可見(jiàn)?
這里涉及到可見(jiàn)性的問(wèn)題。
對(duì)于普通的變量來(lái)說(shuō),每個(gè)線程要想修改變量的值,首先從主存(JMM的定義,在JVM中,大致是可以對(duì)應(yīng)到堆內(nèi)存的)中拷貝值到自己所屬的CPU cache中去?,F(xiàn)在的處理器,一般是會(huì)有多個(gè)CPU的,每個(gè)線程可能運(yùn)行在不同的CPU, 那么線程修改完成的值,是首先保存在CPU cache中去。此時(shí)其他的線程是察覺(jué)不到修改的結(jié)果的,這就造成了并發(fā)模型中的可見(jiàn)性問(wèn)題。
考慮這樣一種情況:
public class SharedObject { public int counter = 0; }
現(xiàn)在有兩個(gè)線程, 線程1和線程2, 他們不時(shí)會(huì)去讀取這個(gè)共享變量。如果counter沒(méi)有聲明volatile這個(gè)關(guān)鍵字,那么此時(shí)就無(wú)法保證counter的值何時(shí)從CPU緩存寫(xiě)回到主存。這意味著,counter在CPU cache中的值和主存中的會(huì)不一致。
但是如果聲明了volatile的話,對(duì)volatile變量進(jìn)行寫(xiě)操作的話,那么JVM就會(huì)向處理器發(fā)送一條LOCK前綴的指令,將這個(gè)變量所在緩存行中的數(shù)據(jù)寫(xiě)回到系統(tǒng)內(nèi)存。
寫(xiě)回的過(guò)程,為了保證各個(gè)處理器的緩存是一一致的,就會(huì)實(shí)現(xiàn)緩存一致性協(xié)議。
緩存不停地窺探總線上發(fā)生的數(shù)據(jù)交換,來(lái)檢查自己的數(shù)據(jù)是不是已經(jīng)過(guò)期了。如果發(fā)現(xiàn)此時(shí)緩存行中的值已經(jīng)失效的話,就會(huì)將當(dāng)前緩存行中的值設(shè)置為無(wú)效狀態(tài)。處理器要用到這個(gè)值的話,就會(huì)從內(nèi)存中重新獲取這個(gè)值。
禁止指令重排序
指令重排序是指CPU采用了允許將多條指令不按照程序規(guī)定的順序分開(kāi)發(fā)送給各相應(yīng)的電路單元處理
TODO --
參考:
https://blog.usejournal.com/j...
https://medium.com/@siddhusin...
https://www.cnblogs.com/dolph...
《Java特種兵》
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/75209.html
摘要:前提深入理解內(nèi)存模型程曉明著,該書(shū)在以前看過(guò)一遍,現(xiàn)在學(xué)的東西越多,感覺(jué)那塊越重要,于是又再細(xì)看一遍,于是便有了下面的讀書(shū)筆記總結(jié)。同步同步是指程序用于控制不同線程之間操作發(fā)生相對(duì)順序的機(jī)制。線程之間的通信由內(nèi)存模型控制。 showImg(https://segmentfault.com/img/remote/1460000013474312?w=1920&h=1271); 前提 《深...
摘要:前提深入理解內(nèi)存模型程曉明著,該書(shū)在以前看過(guò)一遍,現(xiàn)在學(xué)的東西越多,感覺(jué)那塊越重要,于是又再細(xì)看一遍,于是便有了下面的讀書(shū)筆記總結(jié)。同步同步是指程序用于控制不同線程之間操作發(fā)生相對(duì)順序的機(jī)制。線程之間的通信由內(nèi)存模型控制。 showImg(https://mmbiz.qpic.cn/mmbiz_jpg/1flHOHZw6RtPu3BNx3zps1JhSmPICRw7QgeOmxOfTb...
摘要:的線程機(jī)制是搶占式。會(huì)讓出當(dāng)多個(gè)線程并發(fā)的對(duì)主存中的數(shù)據(jù)進(jìn)行操作時(shí),有且只有一個(gè)會(huì)成功,其余均失敗。和對(duì)象只有在困難的多線程問(wèn)題中才是必須的。 并發(fā)簡(jiǎn)述 并發(fā)通常是用于提高運(yùn)行在單處理器上的程序的性能。在單 CPU 機(jī)器上使用多任務(wù)的程序在任意時(shí)刻只在執(zhí)行一項(xiàng)工作。 并發(fā)編程使得一個(gè)程序可以被劃分為多個(gè)分離的、獨(dú)立的任務(wù)。一個(gè)線程就是在進(jìn)程中的一個(gè)單一的順序控制流。java的線程機(jī)制是...
摘要:關(guān)鍵字總結(jié)有個(gè)關(guān)鍵字,它們是接下來(lái)對(duì)其中常用的幾個(gè)關(guān)鍵字進(jìn)行概括。而通過(guò)關(guān)鍵字,并不能解決非原子操作的線程安全性。為了在一個(gè)特定對(duì)象的一個(gè)域上關(guān)閉,可以在這個(gè)域前加上關(guān)鍵字。是語(yǔ)言的關(guān)鍵字,用來(lái)表示一個(gè)域不是該對(duì)象串行化的一部分。 java 關(guān)鍵字總結(jié) Java有50個(gè)關(guān)鍵字,它們是: abstract do implements private ...
摘要:最近在看多線程相關(guān),看到這篇來(lái)自大神關(guān)于關(guān)鍵字的講解感覺(jué)非常詳細(xì)易懂,特此轉(zhuǎn)載一下。如果對(duì)增加聲明則所有線程對(duì)的寫(xiě)都會(huì)立即刷新到主存中,而且所有對(duì)的讀也都直接從主存中去讀。 最近在看java多線程相關(guān),看到這篇來(lái)自大神Jakob Jenkov關(guān)于Volatile關(guān)鍵字的講解感覺(jué)非常詳細(xì)易懂,特此轉(zhuǎn)載一下。原文鏈接:http://tutorials.jenkov.com/j... 內(nèi)存可...
閱讀 1185·2021-11-16 11:42
閱讀 2969·2021-10-12 10:18
閱讀 2910·2021-09-24 09:48
閱讀 3530·2019-08-30 15:56
閱讀 1596·2019-08-30 14:17
閱讀 3096·2019-08-29 12:14
閱讀 969·2019-08-27 10:51
閱讀 2083·2019-08-26 13:28