亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java變量的可見性問題實例分析

發布時間:2022-03-15 17:33:45 來源:億速云 閱讀:167 作者:iii 欄目:web開發

這篇文章主要介紹了Java變量的可見性問題實例分析的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Java變量的可見性問題實例分析文章都會有所收獲,下面我們一起來看看吧。

問題:synchorized,sleep 也能達到volatile 線程可見性的目的?,大致的問題描述如下:

package com.test;

import java.util.concurrent.TimeUnit;

public class test1 {

private static boolean is = true;

public static void main(String[] args) {

new Thread(new Runnable() {

@Override

public void run() {

int i = 0;

while(test1.is){

i++;

1 //synchronized (this) { } 會強制刷新主內存的變量值到線程棧?

2 //System.out.println("1"); println 是synchronized 的,會強制刷新主內存的變量值到線程棧?

3 //sleep 會從新load主內存的值?

// try {

// TimeUnit.MICROSECONDS.sleep(1);

// }catch (InterruptedException e) {

// e.printStackTrace();

// }

}

}

}).start();

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

new Thread(new Runnable() {

@Override

public void run() {

is = false; //設置is為false,使上面的線程結束while循環

}

}).start();

}

}

問: 為什么整個程序不會終止? 為什么取消注釋中的任何一個代碼塊(1,2,3),程序才會終止?synchronized 會強制刷新住內存的變量值到線程棧? sleep 會干什么呢?

涉及知識解釋

volatile:此關鍵字保證了變量在線程的可見性,所有線程訪問由volatile修飾的變量,都必須從主存中讀取后操作,并在工作內存修改后立即寫回主存,保證了其他線程的可見性,同樣效果的關鍵字還有final。

synchronized:所有同步操作都必須保證 1、原子性 2、可見性,所以在同步塊中發生的變化會立馬寫回主存

sleep:此方法只會讓出CPU執行時間,并不會釋放鎖。

問題分析

Q1:為什么注釋代碼后程序不會終止?

A1:因為 boolean is=true 的變量值被前面線程(簡稱線程A)加載到自己的工作內存,在后面的線程(簡稱線程B)改變 boolean is=false 之后不一定會立馬寫入主存(不過這道題中應該會馬上寫入主存,因為線程執行完 is=false之后線程就要退出了),即便立馬寫入了主存后線程A也不一定馬上load到工作內存中,所以程序一直不會終止?這個是我們大多數人想到的,但其實JVM針對現在的硬件水平已經做了很大程度的優化,基本上很大程度的保障了工作內存和主內存的及時同步,相當于默認使用了volatile。但只是最大程度!在CPU資源一直被占用的時候,工作內存與主內存中間的同步,也就是變量的可見性就會不那么及時!后面會驗證結論。

Q2:為什么取消注釋中的任何一個代碼塊(1,2,3),程序才會終止?

A2:行號為1、2的代碼有一個共同特點,就是都涉及到了synchronized 同步鎖,那么是否像提問作者猜想的那樣synchronized會強制刷新主內存的變量值到線程棧?,以及sleep方法也會刷新主存的變量值到線程棧呢?,事實上我們前面說了synchronized只會保證在同步塊中的變量的可見性,而is變量并不在該同步塊中,所以顯然不是這個導致的。接下來我們在代碼i++;后面加上以下代碼:

for(int k=0;k<100000;k++){

new Object();

}

再Run,程序立刻終止!為什么?在上面的 A1 中我們已經說了即便有JVM的優化,但當CPU一直被占用的時候,數據的可見性得不到很好的保證,就像上面的程序一直循環做i++;運算占用CPU,而為什么加上上面的代碼后程序就會停止呢?因為對于大量new Object()操作來說,CPU已經不是主要占時間的操作,真正的耗時應該在內存的分配上(因為CPU的處理速度明顯快過內存,不然也不會有CPU的寄存器了),所以CPU空閑后會遵循JVM優化基準,盡可能快的保證數據的可見性,從而從主存同步is變量到工作內存,最終導致程序結束,這也是為什么sleep()方法雖然沒有涉及同步操作,但是依然可以使程序終止,因為sleep()方法會釋放CPU,但不釋放鎖!

關于“Java變量的可見性問題實例分析”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Java變量的可見性問題實例分析”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

京山县| 龙州县| 峨边| 莲花县| 江口县| 江达县| 石泉县| 西峡县| 东乡族自治县| 龙门县| 邢台市| 衡山县| 图们市| 包头市| 辉县市| 喜德县| 迭部县| 新巴尔虎左旗| 昂仁县| 明光市| 乡城县| 白玉县| 绵阳市| 寻甸| 阿克苏市| 浮山县| 新民市| 板桥市| 西乌珠穆沁旗| 郯城县| 屯昌县| 治县。| SHOW| 南汇区| 涟水县| 尉犁县| 武宣县| 石门县| 大理市| 松溪县| 石渠县|