第二章 對象以及變量的併發訪問

synchronied 對象監視器爲Object時的使用,或者監視器爲Class時的使用。java

 

方法中的變量不存在非線程安全問題,永遠都是線程安全的,這是方法內部的變量是私有的特性形成的。安全

 

 

1 synchronized的使用併發

在方法前加關鍵字synchronized便可。異步

1)A線程先持有object對象的Lock鎖,B線程能夠異步的方式調用object對象中的非synchrionized類型的方法。測試

2)A線程先持有object對象的Lock鎖,B線程若是在這時調用了object對象中的synchrionized類型的方法則須要等待,也就是同步。this

 

2 髒讀線程

每一個方法都加synchronized解決對象

 

3 鎖重入繼承

synchronized方法/塊內部調用其餘synchronized方法/塊的時,是永遠獲得鎖的。內存

「可重入鎖」的概念是:本身能夠再次得到本身的內部鎖。好比有一條線程得到了某個對象的鎖,此時這個對象尚未釋放,當其再次想得到這個對象的鎖的時候仍是能夠得到的,若是不可鎖重入的話,就會形成死鎖。

出現異常,鎖就會自動釋放。

同步不具備繼承性,應該是發生在重寫的狀況下

 

4 synchronized同步代碼塊

當兩個併發線程訪問同一個對象object中的synchronized(this)同步代碼塊時,一段時間內只能有一個線程被執行,另外一個線程必須等待當前線程執行完這個代碼塊之後才能執行該代碼塊之後才能執行該代碼塊。

在使用同步synchronized(this)代碼塊時須要注意的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其餘線程對同一個object中全部其餘synchronized(this)同步代碼塊的訪問被阻塞,這說明synchronized使用的「對象監視器」是一個。

關鍵字synchronized還能夠運用在static靜態方法上,若是這樣寫,那是對當前的*.java文件對應的Class類上鎖。

從運行效果上看,並無說明特別之處,都是同步的效果,和將sychronized關鍵字加到非static方法上使用的效果是同樣的。而sychronized關鍵字加到非static靜態方法上是給對象上鎖。

 

數據類型String的常量池特性:在JVM中具備String常量池緩衝的功能,將

synchronized(String)同步塊與String聯合使用時,要注意帶來的一些意外。通常不使用

同步方法容易形成死循環,用同步塊試一下

 

 

 

 

5 內置類

public class PublicClass{

    class PrivateClass{

    }

}

PublicClass pubc = new PublicClass();

PrivateClass pric = pubc.new PrivateClass;

還有一種靜態內置類

public class PublicClass{

    static class PrivateClass{

    }

}

 

本實驗測試同步代碼塊sychronized(class2)對class2上鎖後,其餘線程只能以同步的方式調用class2中的靜態方法

 

6 volatile 關鍵字

 

主要做用是使變量在多個線程間可見,但不支持原子性

 

i++問題

1)從內存中取出i的值;

2)計算i的值;

3)將i的值寫到內存中。

對於用volatile修飾的變量,JVM虛擬機只是能保證從主內存中加載到線程工做內存的值是最新的,例如線程1和線程2在進行read和load的操做中,發生主內存中的count的值都是5,那麼都會加載這個最新的值,也就是說volatile關鍵字解決的是變量讀時的可見性問題,但沒法保證原子性,對於多個線程訪問同一個實例變量仍是須要加鎖同步。

使用原子類進行i++操做,除了操做時使用synchronized關鍵字實現同步外,還可使用AtomicInt類進行實現。

 

sychronized代碼塊有volaite同步的功能:

` 關鍵字synchronized可使用多個線程訪問同一個資源具備同步性,並且它還具備將線程工做內存中的私有變量與公共內存中的變量同步的功能。

相關文章
相關標籤/搜索