java內存模型FAQ

1. 什麼是內存模型?

在處理器的層面上,內存模型定義了一個充要條件:讓當前處理器能夠看到其餘處理器寫入到內存的數據以及其餘處理器能夠看到當前處理器寫入到內存的數據java

有些處理器有很強的內存模型(strong memory model),可以讓全部處理器在任什麼時候候任何指定的內存地址上均可以看到徹底相同的值。
而另外一些處理器則有較弱的內存模型(weaker memory model),在這種處理器中,必須使用內存屏障來刷新本地處理器緩存並使本地處理器緩存無效,目的是爲了讓當前處理器可以看到其餘處理器的寫操做或者其餘處理器可以看到當前處理器的寫操做。程序員

一個線程的寫操做對其餘線程可見這個問題是由於編譯器對代碼進行重排序致使的。緩存

java內存模型描述了哪些行爲在多線程中是合法的,以及線程如何經過內存進行交互的。它描述了程序中的變量從內存或者寄存器獲取或存儲他們的底層細節之間的關係。安全

2. 其餘語言,像C++,也有內存模型嗎?

大部分其餘的語言,像C和C++,都沒有被設計成直接支持多線程。這些語言對於發生在編譯器和處理器平臺架構的重排序行爲的保護機制會嚴重的依賴於程序中所使用的線程庫(例如pthreads),編譯器,以及代碼所運行的平臺所提供的保障。多線程

3. JSR133是什麼?

JSR133爲java語言定義了一個新的內存模型,它修復了早期內存模型的缺陷。
JSR133的目的是建立一組正式語義,這些正式語義提供了volatile、synchronzied和final如何工做的直觀框架。
JSR133的目標:架構

  1. 保留已經存在的安全保證以及強化其餘的安全保證
  2. 正確同步的程序的語義應該儘可能簡單直觀
  3. 應該定義未完成或者未正確同步的程序的語義,主要是爲了把潛在的安全危害降到最低
  4. 程序員應該可以自信的推斷多線程是如何同內存進行交互的
  5. 可以在如今許多流行的硬件框架中涉及正確以及高性能的JVM實現
  6. 應該儘可能不影響現有的代碼

4. 重排序意味着什麼?

在不少狀況下,訪問一個變量可能會使用不一樣的順序執行,而不是程序語義所指定的順序執行。
編譯器能夠以優化的名義去改變指令順序。在特定環境下,處理器可能會次序顛倒的執行指令。數據可能在寄存器,處理器緩衝區和主內存中以不一樣的次序移動,而不是按照指定的順序。
編譯器,運行時和硬件被指望一塊兒合力建立好像是順序執行的語義的假象,這意味着在單線程的程序中,程序應該是不可以觀察到重排序的影響的。可是,重排序在沒有正確同步了的多線程程序中開始起做用,在這些多線程程序中,一個線程可以觀察到其餘線程的影響,也可能檢測到其餘線程將會以一種不一樣於程序語義所規定的執行順序來訪問變量。框架

5. 舊的內存模型有什麼問題?

舊的內存模型中有幾個嚴重的問題。這些問題很難理解,所以被普遍的違背。例如,舊的存儲模型在許多狀況下,不容許JVM發生各類重排序行爲。
就如final字段,使用了此字段的變量是不可變的,不須要使用同步,可是就在舊的程序中final變量並無被區別對待,這覺得着同步才能保證final字段的惟一性。
舊的內存模型容許volatile變量的寫操做和非volaitle變量的讀寫操做一塊兒進行重排序,這和大多數的開發人員對於volatile變量的直觀感覺是不一致的,所以會形成迷惑。性能

6. 沒有正確同步的含義是什麼?

在Java內存模型這個語義環境下,咱們談到「沒有正確同步」,咱們的意思是:優化

  1. 一個線程中有一個對變量的寫操做,
  2. 另一個線程對同一個變量有讀操做,
  3. 並且寫操做和讀操做沒有經過同步來保證順序。

當這些規則被違反的時候,咱們就說在這個變量上有一個「數據競爭」(data race)。一個有數據競爭的程序就是一個沒有正確同步的程序。線程

7. 同步會作些什麼?

同步有幾方面的做用。首先就是互斥
互斥:一次只有一個線程可以得到一個監視器,所以,在一個監視器上面同步意味着一旦一個線程進入到監視器保護的同步塊中,其餘的線程都不能進入到同一個監視器保護的塊中間,除非第一個線程退出了同步塊。
同步的含義比互斥更廣
同步保證了一個線程在同步塊以前或者在同步塊中的內存寫入操做以可預知的方式對其餘有相同監視器的線程可見。



相關文章
相關標籤/搜索