成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

入坑兩個月自研非外包創業公司,居然讓我搞懂了Volatile

開發 前端
這篇文章嘗試站在年輕同學的角度,用最簡單的大白話,加上多張圖給大家說一下,Volatile到底是什么?

一、場景引入,問題初現

很多同學出去面試,都會被問到一個常見的問題:說說你對volatile的理解?

不少初出茅廬的同學可能會有點措手不及,因為可能就是之前沒關注過這個。但是網上百度一下呢,不少文章寫的很好,但是理論扎的太深,文字太多,圖太少,讓人有點難以理解。

基于上述痛點,這篇文章嘗試站在年輕同學的角度,用最簡單的大白話,加上多張圖給大家說一下,volatile到底是什么?

當然本文不會把理論扎的太深,因為一下子扎深了文字太多,很多同學還是會不好理解。

本文僅僅是定位在用大白話的語言將volatile這個東西解釋清楚,而涉及到特別底層的一些原理和技術問題,以后有機會開文再寫。

首先,給大家上一張圖,咱們來一起看看:

如上圖,這張圖說的是java內存模型中,每個線程有自己的工作內存,同時還有一個共享的主內存。

舉個例子,比如說有兩個線程,他們的代碼里都需要讀取data這個變量的值,那么他們都會從主內存里加載data變量的值到自己的工作內存,然后才可以使用那個值。

好了,現在大家從圖里看到,每個線程都把data這個變量的副本加載到了自己的工作內存里了,所以每個線程都可以讀到data = 0這個值。

這樣,在線程代碼運行的過程中,對data的值都可以直接從工作內存里加載了,不需要再從主內存里加載了。

那問題來了,為啥一定要讓每個線程用一個工作內存來存放變量的副本以供讀取呢?我直接讓線程每次都從主內存加載變量的值不行嗎?

很簡單!因為線程運行的代碼對應的是一些指令,是由CPU執行的!但是CPU每次執行指令運算的時候,也就是執行我們寫的那一大坨代碼的時候,要是每次需要一個變量的值,都從主內存加載,性能會比較差!

所以說后來想了一個辦法,就是線程有工作內存的概念,類似于一個高速的本地緩存。

這樣一來,線程的代碼在執行過程中,就可以直接從自己本地緩存里加載變量副本,不需要從主內存加載變量值,性能可以提升很多!

但是大家思考一下,這樣會有什么問題?

我們來設想一下,假如說線程1修改了data變量的值為1,然后將這個修改寫入自己的本地工作內存。那么此時,線程1的工作內存里的data值為1。

然而,主內存里的data值還是為0!線程2的工作內存里的data值還是0啊?!

這可尷尬了,那接下來,在線程1的代碼運行過程中,他可以直接讀到data最新的值是1,但是線程2的代碼運行過程中讀到的data的值還是0!

就導致,線程1和線程2其實都是在操作一個變量data,但是線程1修改了data變量的值之后,線程2是看不到的,一直都是看到自己本地工作內存中的一個舊的副本的值!

這就是所謂的java并發編程中的可見性問題:

多個線程并發讀寫一個共享變量的時候,有可能某個線程修改了變量的值,但是其他線程看不到!也就是對其他線程不可見!

二、volatile的作用及背后的原理

那如果要解決這個問題怎么辦呢?這時就輪到volatile閃亮登場了!你只要給data這個變量在定義的時候加一個volatile,就直接可以完美的解決這個可見性的問題。

比如下面的這樣的代碼,在加了volatile之后,會有啥作用呢?

完整的作用就不給大家解釋了,因為我們定位就是大白話,要是把底層涉及的各種內存屏障、指令重排等概念在這里帶出來,不少同學又要蒙圈了!

我們這里,就說說他最關鍵的幾個作用是啥?

第一,一旦data變量定義的時候前面加了volatile來修飾的話,那么線程1只要修改data變量的值,就會在修改完自己本地工作內存的data變量值之后,強制將這個data變量最新的值刷回主內存,必須讓主內存里的data變量值立馬變成最新的值!

整個過程,如下圖所示:

第二,如果此時別的線程的工作內存中有這個data變量的本地緩存,也就是一個變量副本的話,那么會強制讓其他線程的工作內存中的data變量緩存直接失效過期,不允許再次讀取和使用了!

整個過程,如下圖所示:

第三,如果線程2在代碼運行過程中再次需要讀取data變量的值,此時嘗試從本地工作內存中讀取,就會發現這個data = 0已經過期了!

此時,他就必須重新從主內存中加載data變量最新的值!那么不就可以讀取到data = 1這個最新的值了!整個過程,參見下圖:

?bingo!好了,volatile完美解決了java并發中可見性的問題!

對一個變量加了volatile關鍵字修飾?之后,只要一個線程修改了這個變量的值,立馬強制刷回主內存。

接著強制過期其他線程的本地工作內存中的緩存,最后其他線程讀取變量值的時候,強制重新從主內存來加載最新的值!

這樣就保證,任何一個線程修改了變量值,其他線程立馬就可以看見了!這就是所謂的volatile保證了可見性的工作原理!

三、總結 & 提醒

?最后給大家提一嘴,volatile主要作用是保證可見性以及有序性。

有序性涉及到較為復雜的指令重排、內存屏障等概念,本文沒提及,但是volatile是不能保證原子性的!

也就是說,volatile主要解決的是一個線程修改變量值之后,其他線程立馬可以讀到最新的值,是解決這個問題的,也就是可見性!

但是如果是多個線程同時修改一個變量的值,那還是可能出現多線程并發的安全問題,導致數據值修改錯亂,volatile是不負責解決這個問題的,也就是不負責解決原子性問題!

原子性問題,得依賴synchronized、ReentrantLock等加鎖機制來解決。?

責任編輯:姜華 來源: 今日頭條
相關推薦

2013-11-27 09:26:02

遠程公司

2015-11-19 13:41:57

創業外包公司

2014-06-25 09:26:16

創業創業失敗

2025-02-28 09:30:00

?DeepSeekDeepGEMMAI

2012-09-03 14:38:57

2023-10-11 08:18:22

RocketMQ邏輯訂閱

2024-12-30 07:05:00

AI費馬大定理人工智能

2018-04-18 09:07:24

iPhone X手機利潤

2020-07-02 09:15:59

Netty內存RPC

2020-09-28 15:43:03

計算機互聯網 技術

2019-06-12 09:29:44

華為禁令開發

2025-02-08 08:30:00

2018-08-09 09:00:34

Hadoop制造行業國內企業

2012-01-11 11:13:06

惠普ProLiant

2020-06-19 15:05:43

GitHub 開發面試

2021-11-30 10:06:40

Windows 11Windows微軟

2021-09-15 13:31:44

語言項目技術棧scala

2016-11-09 16:52:20

Android 7.0谷歌安卓

2022-03-21 14:37:17

數據存儲服務器IT

2022-02-23 14:43:52

程序員猝死996
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久久久久久久久国产 | 欧美在线视频一区二区 | 国产综合精品一区二区三区 | 91美女在线观看 | 精品久久一区 | 精品免费国产视频 | 日韩在线观看中文字幕 | 欧美精品一区二区三区在线播放 | 国产精品久久久久久久久图文区 | 国产精品1区2区3区 一区中文字幕 | 久久久久久影院 | 日韩精品一区二区三区中文在线 | 成人永久免费视频 | 国产精品美女久久久久久免费 | 久久国产精品亚洲 | 国产成人自拍av | 在线观看免费国产 | 99国产精品久久久 | 色婷婷国产精品综合在线观看 | 红桃成人在线 | 国产精品伦一区二区三级视频 | 亚洲网址在线观看 | 精品在线视频播放 | 91视频91| 久久r精品| 91在线观看免费视频 | 成人影视网| 婷婷丁香在线视频 | 91成人免费观看 | 国产大学生情侣呻吟视频 | 中文在线视频观看 | 成人精品一区亚洲午夜久久久 | 亚洲一一在线 | 久久久免费毛片 | 欧美a级成人淫片免费看 | 国产一级视频在线播放 | 中文字幕人成人 | 精品久久香蕉国产线看观看亚洲 | 中文字幕av一区二区三区 | 国产精品久久久久久52avav | 日韩欧美国产成人一区二区 |