volatile
volatile保證了多線程之間的可見性。用volatile修飾的變量,在多個線程中都可以讀到最新的值,但是不保證變量的原子性。
那么volatile如何保證多線程之間的可見性呢?
首先,需要說明下線程安全問題引起的原因。每個線程在計算的時候會讀取主內(nèi)存中的數(shù)據(jù)到本地變量表中,計算后再將數(shù)據(jù)寫回到主內(nèi)存中。假設(shè),每個線程讀取到的主內(nèi)存中的數(shù)據(jù)的值是一致的,在各自線程內(nèi)存中計算后,會得到不同的結(jié)果,這個時候再講結(jié)果會寫到主內(nèi)存中,那么先寫回主內(nèi)存中的線程的計算過程就被覆蓋掉了。這樣就造成了線程安全問題。
被volatile修飾的變量,對于虛擬機來說就是被共享的變量,所以不會在該變量上進行指令的重排序,也不會在線程內(nèi)存中緩存該變量,直接在主內(nèi)存中存取,所以保證了每個線程讀取到的數(shù)據(jù)都是最新的。
synchronized
synchronized關(guān)鍵字可以修飾代碼塊、方法、靜態(tài)方法以及類。用sysnchronized時要注意鎖定的是對象還是類,如果鎖定的是類,相當于鎖定了該類的所有對象。
synchronized修飾的方法或者代碼塊,使該方法和代碼塊對多線程互斥,只有一個線程可以進入該方法或者代碼塊(方法或者代碼塊以下統(tǒng)稱為方法,便于說明)。多個線程訪問synchronized修飾的方法時,會嘗試獲取對象的mointor鎖,當獲取到mointor時可以進入該同步方法進行運算,沒有獲取到mointor鎖的線程會存在虛擬機的一個synchronized的隊列中,當mointor被釋放的時候,從synchronized隊列中出一個線程獲取mointor鎖
