1. 程式人生 > >synchronized修飾方法和對象的區別

synchronized修飾方法和對象的區別

關系型 target volitile 個數 同步 知識庫 樂觀鎖 title 調用

使用synchronized(object) { 代碼塊.... } 能對代碼塊進行加鎖,不允許其他線程訪問,其的作用原理是:在object內有一個變量,當有線程進入時,判斷是否為0,如果為0,表示可進入執行該段代碼,同時將該變量設置為1,這時其他線程就不能進入;當執行完這段代碼時,再將變量設置為0。

想保證代碼塊在任務情況下都同步,即代碼塊在程序的中同一時刻只被一個線程調用,即需要使用synchronized( static object)。

object必須是靜態變量,否則不同對象調用該方法時也不能同步。

這種技術可以應用在實現Java層的悲觀鎖,例如在DAO類中希望用悲觀鎖控制某個方法同步(整個app中每次只允許一個線程同時調用)。

至於在JAVA中實現樂觀鎖,就可以使用volitile變量,在方法開始時將變量先+1,獲取值,然後在方法完成時判斷該值是否為方法開始時+1的值,如果不是,則表示有其他線程修改過。

使用synchronized修飾方法,當一個線程進入這個方法後,這個方法的大門就會暫時關閉(不許其他線程進入)直到這個線程走出這個方法後,該方法的大門才會敞開。當然,這個關閉只是對於該類的當前實例有效,多個實例的對象仍然可以同時執行。

悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關系型數據庫裏邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。

樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量,像數據庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。

兩種鎖各有優缺點,不可認為一種好於另一種,像樂觀鎖適用於寫比較少的情況下,即沖突真的很少發生的時候,這樣可以省去了鎖的開銷,加大了系統的整個吞吐量。但如果經常產生沖突,上層應用會不斷的進行retry,這樣反倒是降低了性能,所以這種情況下用悲觀鎖就比較合適

synchronized修飾方法和對象的區別