Java-多線程-並行控制-synchronized與volatile

  • #synchronized與volatile

    synchronized用來實現資源利用的互斥性,被其標識的區間同一時間只允許一個線程運行。
    volatile被用於設計可見性,指的是一個線程操作完一個資源後,另一個線程獲取到的一定是最新的資源數據,而不是緩存      

#synchronized
    
    @每個對象內部都有一個內部鎖定(監控鎖定),被標識爲synchronized的代碼塊會被監控,任何線程要執行該代碼塊都必須先取得指定對象的內部鎖定。多線程下競爭同一個鎖定時,未競爭到的線程將進入等待鎖定狀態(blocked狀態)。
    
    @synchronized的使用方法
        1.用來標識方法
        2.用來標識代碼塊

//標識在方法上
...
    public void synchronized functionA(){
        ...
    }
...

//標識一個代碼塊
...
    public void functionB(){
        ...
        synchronized(this){
            ...
        }
        ...
    }
...


        
    @synchronized默認是獲取當前代碼塊或者方法所在類或者類的實例的鎖定。

    @Collection與Map可以使用Collections的下列方法進行打包,以獲取對應的據有線程安全的對象。
        Collections.synchronizedCollection()
        Collections.synchronizedList()
        Collections.synchronizedSet()
        Collections.synchronizedMap()
        ...
        
    @synchronized提供的是可重入同步,也就是說線程取得某個對象的鎖定後,若執行過程中又要獲取該鎖定,則可以直接執行。
    
    @對於synchronized設計不當,有可能造成“死結”, 即多線程下,線程之間對資源彼此交叉取用有可能造成“死結”。
    
 

#volatile

    @在變量上標識volatile,表示變量是異變的,不允許線程快取,也就是如果有線程變動了變量值,另一個線程一定可以看到變更。
    
#競爭對象資源下的等待與通知
    下面三個方法都是Object定義的方法。
    1.wait(),執行synchronized範圍內的代碼時,如果調用了鎖定對象的wait()方法,線程會釋放對象鎖定,並進入對象的等待集合,並且狀態變更爲Blocked,這時其它線程可以繼續競爭對象鎖定。wait()還可以指定時間,時間到了之後線程會再次加入對鎖定的競爭。如果不指定時間,線程會一直等待下去,直到被中斷(調用interrupt()方法)或被通知繼續參與競爭(調用對象的notify()、notifyAll())。
    
    2.notify(),從對象的等待集合中隨機通知一個線程加入排班(即將鎖定交給了它)。
    
    3.notifyAll(),通知等待集合中所有的線程重新參與鎖定的競爭。
    
    
#特別注意事項
    
    多線程下,線程可能在未經過notify()、notifyAll()、interrupt()或逾時等情況下私自甦醒,應用程序設計時應該考慮這種情況,wait()在條件式成立的循環中執行。
    
    
    
    
    
    
    
    

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章