五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

java線程執(zhí)行過程中改變量值的結(jié)果引起的思考

2021-11-28 13:25 作者:寂風(fēng)也過路  | 我要投稿

注:筆者在研究volatile關(guān)鍵詞的使用時(shí),意外發(fā)現(xiàn)了以下四種案例情況,感覺頗為神奇,于是進(jìn)行記錄。限于筆者才疏學(xué)淺,無法暫時(shí)無法更進(jìn)一步研究問題的本質(zhì)與底層的內(nèi)容,所以希望能夠拋磚引玉,得來更多更優(yōu)秀深入的見解。

1.第一種情況

尋常情況下,線程執(zhí)行過程中突然對其變量進(jìn)行變動(dòng)

這是最尋常的問題,run方法中將active設(shè)為true后,while一直用的就是這個(gè)true,不會(huì)去內(nèi)存中刷新這個(gè)值,也就導(dǎo)致了while死循環(huán)。

線程:

1-1

測試:

1-2

2.第二種情況

對變量使用volatile關(guān)鍵字修飾情況下,線程執(zhí)行過程中突然對其變量進(jìn)行變動(dòng)

加上volatile關(guān)鍵字后,每次使用到active變量都將拿到最新的值,所以stop方法改active的值后,while就能拿到最新的active值為false,然后結(jié)束循環(huán)。

注:(源自https://www.runoob.com/java/java-modifier-types.html的volatille關(guān)鍵字解釋)

volatile 修飾的成員變量在每次被線程訪問時(shí),都強(qiáng)制從共享內(nèi)存中重新讀取該成員變量的值。而且,當(dāng)成員變量發(fā)生變化時(shí),會(huì)強(qiáng)制線程將變化值回寫到共享內(nèi)存。這樣在任何時(shí)刻,兩個(gè)不同的線程總是看到某個(gè)成員變量的同一個(gè)值。

線程:

2-1

測試:

2-2

3.第三種情況

這種情況比較特殊,在while循環(huán)中加入輸入打印語句下,線程執(zhí)行過程中突然對其變量進(jìn)行變動(dòng)

線程:

3-1

測試:

3-2

那么為什么輸出語句能導(dǎo)致run方法的while循環(huán)發(fā)現(xiàn)active已經(jīng)被修改了呢?因?yàn)閜rintln里有用到了synchronized這個(gè)同步關(guān)鍵字。

如圖:

3-3

而synchronized將導(dǎo)致(解釋源自:https://blog.csdn.net/qq_28082757/article/details/101065531):

  1. 獲得同步鎖;

  2. 清空工作內(nèi)存;

  3. 從主內(nèi)存拷貝對象副本到工作內(nèi)存;? ?

  4. 執(zhí)行代碼(計(jì)算或者輸出等);

  5. 刷新主內(nèi)存數(shù)據(jù);

  6. 釋放同步鎖。

所以真正的起作用的不是輸出語句,而是synchronized,把輸出語句換成什么都沒做的同步區(qū)塊也能實(shí)現(xiàn)相同的效果。

如圖:

3-4

但是,這又產(chǎn)生了另一個(gè)問題:為什么在Stop方法里用到輸出語句(也是內(nèi)部的synchronized起作用),不會(huì)影響while這個(gè)方法的active讀取呢?難道作用的只是這個(gè)方法內(nèi)數(shù)據(jù)刷新,而不是整個(gè)線程?

我將stop方法中的輸出語句放在active修改后,想著是否能夠因?yàn)閟ynchronized的數(shù)據(jù)刷新使得while發(fā)現(xiàn)active已經(jīng)變了,于是停下來,然而并沒有。

如圖:

那么,這又是為什么呢?

因?yàn)檎麄€(gè)運(yùn)行過程存在兩個(gè)線程,一個(gè)是main線程,一個(gè)volatileTestThread2線程。

兩個(gè)線程都有一個(gè)active的變量的副本在它們的工作內(nèi)存中(真正的active是放在主內(nèi)存中)

run方法在volatileTestThread2內(nèi)調(diào)用運(yùn)行,所以synchronized影響的是volatileTestThread2的工作內(nèi)存里變量的與主內(nèi)存之間的刷新

stop方法是main線程調(diào)用的,所以synchronized是影響main線程的工作內(nèi)存與主內(nèi)存之間的刷新。

二者是不同的。

這也就解釋了“為什么在Stop方法里用到輸出語句(也是內(nèi)部的synchronized起作用),不會(huì)影響while這個(gè)方法的active讀取呢?”這個(gè)問題。

4.第四種情況

在while循環(huán)中加入Sleep下,線程執(zhí)行過程中突然對其變量進(jìn)行變動(dòng)

線程:

4-1

測試:

4-2

我們都知道,Sleep將使得線程進(jìn)入休眠(等待狀態(tài)),操作系統(tǒng)調(diào)度程序不調(diào)度睡眠線程以接收CPU時(shí)間。

那么等待狀態(tài)結(jié)束后,線程進(jìn)入就緒狀態(tài)以及被調(diào)度選中后執(zhí)行的這個(gè)過程,線程是否是進(jìn)行了內(nèi)存變量的刷新?或者是進(jìn)行了某些底層處理,導(dǎo)致產(chǎn)生了和前文synchronized使用后一樣的結(jié)果?

正在研究中...

這是筆者的github的測試項(xiàng)目地址:https://github.com/17lhf/happyTest

可以查看完整的代碼。

java線程執(zhí)行過程中改變量值的結(jié)果引起的思考的評論 (共 條)

分享到微博請遵守國家法律
兴和县| 香格里拉县| 台中县| 苗栗县| 绿春县| 偃师市| 英吉沙县| 江达县| 德令哈市| 漾濞| 东兴市| 佛坪县| 崇文区| 彰武县| 扎赉特旗| 九江市| 肃南| 张家川| 屏南县| 呼玛县| 台东市| 富民县| 宣恩县| 江西省| 天祝| 江华| 温州市| 常州市| 桦川县| 拉孜县| 丹东市| 龙山县| 讷河市| 大石桥市| 潼关县| 商丘市| 洛川县| 瓮安县| 微博| 榆林市| 修文县|