在看ConcurrentHashMap的雜記

static final int MAXIMUM_CAPACITY = 1 << 30;
//32位的int最大值+1的一半
//(1073741824 0100 0000 0000 0000 0000 0000 0000 0000)
最大值MAX_VALUE = 0x7fffffff;
//(2147483647 0111 1111 1111 1111 1111 1111 1111 1111)

transient
意思是轉瞬即逝的,它所修飾的變量將不被序列化,例如Thread就是這類的。另外static的變量和對象的方法也是不會被序列化的。

volatile
飛行的, 揮發性的, 可變的, 不穩定的, 輕快的, 爆炸性的
揮發物
class Gadget
{
public:
void Wait()
{
while (!flag_)
{
Sleep(1000); // sleeps for 1000 milliseconds
}
}
void Wakeup()
{
flag_ = true;
}
...
private:
bool flag_;
};

假設編譯器發現Sleep(1000)是調用一個外部的庫函數,它不會改變成員變量flag_,那麼編譯器就可以斷定它可以把flag_緩存在寄存器中,以後可以訪問該寄存器來代替訪問較慢的主板上的內存。這對於單線程代碼來說是一個很好的優化,但是在現在這種情況下,它破壞了程序的正確性:當你調用了某個Gadget的Wait函數後,即使另一個線程調用了Wakeup,Wait還是會一直循環下去。這是因爲flag_的改變沒有反映到緩存它的寄存器中去。編譯器的優化未免有點太……樂觀了。

在大多數情況下,把變量緩存在寄存器中是一個非常有價值的優化方法,如果不用的話很可惜。C和 C++給你提供了顯式禁用這種緩存優化的機會。如果你聲明變量是使用了volatile修飾符,編譯器就不會把這個變量緩存在寄存器裏——每次訪問都將去存取變量在內存中的實際位置。這樣你要對 Gadget的Wait/Wakeup做的修改就是給flag_加上正確的修飾:volatile.

關於volatile還有很多內容,見http://bbs.loveunix.net/viewthread.php?tid=8404。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章