關於volatile的乙個有趣demo

2021-10-19 14:39:10 字數 1663 閱讀 6924

這是乙個測試volatile的例子。

首先我們td不新增volatile,以下的邏輯,建立乙個執行緒讓它去修改該flag,但不是讓它立刻去修改,,而是先讓子執行緒休息一段時間,好讓主線程進入狂讀flag的狀態,這樣做是為了防止低執行強度下 cpu主動重新整理了快取。之後我們進行修改。

public class volatiletest }}

}class threaddemo implements runnable catch (interruptedexception e)

flag = true;

system.out.println("falg=" + flag);

}public boolean isflag()

public void setflag(boolean flag)

}

得到結果如下

falg=true
我們發現子執行緒的值已經進行修改,但這並不能證明記憶體中的值已被寫入。

為證明記憶體裡的已經被寫入,只是主線程沒讀取罷了,做了如下測試

public class volatiletest }}

static class threaddemo implements runnable catch (interruptedexception e)

flag = true;

system.out.println("falg=" + flag);

}public boolean isflag()

public void setflag(boolean flag)

}static class threaddemo2 implements runnable catch (interruptedexception e)

system.out.println("threaddemo2" + volatiletest.td.flag);}}

}

得到結果

falg=true

threaddemo2true

因為demo2執行緒是等了一秒後才從記憶體開始讀,由此證明只是主線層沒有重新整理快取。

接下來我們加上volatile。

public class volatiletest }}

}class threaddemo implements runnable catch (interruptedexception e)

flag = true;

system.out.println("falg=" + flag);

}public boolean isflag()

public void setflag(boolean flag)

}

得到結果如下。

***************=

falg=true

表示該值再被重新讀取時,會被及時重新整理。

通過這幾個demo得出結論正常的寫入操作會被及時寫入記憶體,但並不會通知其他的執行緒,讀取操作就是正常的copy記憶體中的資料,並放到快取中。加上volatile的寫入,可以在其他執行緒發生讀取時,及時的重新整理快取。當然volatile也有禁止重排序的功能,在本篇不進行測試。

乙個有趣的函式 關於時間

最近做專案中要做乙個限制每天領獎的次數,以及每週的領獎的次數。如何判斷上次記錄的時間是否和今天是同一天呢?可能大家一開始的思路就是過24小時不就一天了嗎?呵呵,確實不錯,可是現在區分的是 是否是相同的一天。這就清晰了,只要知道今天是今年的多少天和上次記錄的時間一比較就可以了唄。我把 貼一下,由於是在...

關於乙個有趣遞增的心得

首先申明這是乙個藍點工作室的任務,題目是這樣的 要求編寫乙個程式,實現從鍵盤輸入n 1 n 9 然後輸出一下內容 1 12 22 24 3 33 333 369 n nn nnn n n 當我一開始看見這道題時,第一反應時挺簡單的,迴圈就可以完成,但是仔細一想,不僅要完成迴圈n項的遞增,數字也要疊加...

關於const的乙個有趣的現象

先上 include using namespace std intmain 輸出0 10 並且兩個 c跟d是同乙個值 懷疑是編譯優化把輸出改成字面常量了,但是用gcc編譯時開o0和 e發現跟猜想並不一樣,確實是輸出變數。1 既然編譯器允許去掉const修飾符,那通過指標或者引用修改const變數會...