淺談對synchronized和volatile理解

1.什麼是多線程?併發和並行的區別?

     多線程其實就是合理利用cpu的資源去處理一個程序,多個線程去處理一個程序。

      併發:是指在cpu的調度下,多個線程在處理一個程序,只是因爲cpu調度的速度很快,就造成了,多個線程在同時處理一個程序的假象。不是真正的同時。

      並行:指一個多個cpu實例或多臺機器同時去處理同一程序,是真正的同時。

2.線程的狀態

一個新的線程首先進入Runnable(就緒態),然後等待cpu分配資源,進入Running(運行態)時,如果有synchronized關鍵字(釋放鎖),則需要通過synchronized來排隊(同步),進入等待,等待notify(),notifyAll(),interrupt()來恢復鎖,重新進入就緒態等待,再進入到運行態,然而sleep(),join()也會引起線程阻塞,要等待I/O完成或sleep()中斷或join中斷,才能繼續,如果有異常或者運行結束,線程就結束了。Thread類中的yield方法可以讓一個running狀態的線程轉入runnable。

synchronized在sleep()或者等待I/O完成的過程中不會釋放,意思就是這個線程就算在休眠時,別的線程也不可以來訪問這個線程訪問的資源,而這個問題可以lock來解決。

3.synchronized和lock

 兩者都是爲了解決同步問題,處理資源爭端而產生的技術。功能類似但有一些區別。

lock更靈活,可以自由定義多把鎖的枷鎖解鎖順序(synchronized要按照先加的後解順序)
提供多種加鎖方案,lock 阻塞式, trylock 無阻塞式, lockInterruptily 可打斷式, 還有trylock的帶超時時間版本。
本質上和監視器鎖(即synchronized是一樣的)
能力越大,責任越大,必須控制好加鎖和解鎖,否則會導致災難。
和Condition類的結合。

總的來說:

synchronized的優點就是實現簡單,語義清晰,便於JVM堆棧跟蹤,加鎖解鎖過程由JVM自動控制,提供了多種優化方案,使用更廣泛。其缺點是悲觀的排他鎖,不能進行高級功能

lock的優點是可定時的、可輪詢的與可中斷的鎖獲取操作,提供了讀寫鎖、公平鎖和非公平鎖。缺點是需手動釋放鎖unlock,不適合JVM進行堆棧跟蹤。 

他們的相同點就是他們都是可重入鎖

4.volatile 與 synchronized 的比較

線程安全性包括兩個方面,①可見性。②原子性。

volatile主要用在多個線程感知實例變量被更改了場合,從而使得各個線程獲得最新的值。它強制線程每次從主內存中講到變量,而不是從線程的私有內存中讀取變量,從而保證了數據的可見性。當volatile修飾變量時會禁止指令重排序(有序性)

synchronized可以保證在同一個時刻,只有一個線程可以執行某個方法或者某個代碼塊(保證線程同步,線程是安全的),同時我們還應該注意到synchronized另外一個重要的作用,synchronized可保證一個線程的變化(主要是共享數據的變化)被其他線程所看到(保證可見性,完全可以替代Volatile功能)

兩者之間的比較比較:

①volatile輕量級,只能修飾變量。synchronized重量級,還可修飾方法。

②volatile只能保證數據的可見性,不能用來同步,因爲多個線程併發訪問volatile修飾的變量不會阻塞。

synchronized不僅保證可見性,而且還保證原子性,因爲,只有獲得了鎖的線程才能進入臨界區,從而保證臨界區中的所有語句都全部執行。多個線程爭搶synchronized鎖對象時,會出現阻塞。

從線程的安全性來說:使用volatile並不能保證線程安全性。而synchronized則可實現線程的安全性。

 

參考:

https://www.cnblogs.com/wxd0108/p/5479442.html

https://www.cnblogs.com/hapjin/p/5492880.html

 

 

 

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