java 鎖和synchronizied的區別

java 在多線程併發編程中,爲了線程安全,我們需要對線程數據進行同步,一般的實現方式就是synchronized和重入鎖Lock(ReetrantLock,ReadWriterLock等)

共同點:

都是通過加鎖方式來實現同步,而且都是阻塞式同步(也就是一個線程進入同步代碼塊,其他線程就在外面等待)。

區別:synchronized是java關鍵字,是原生態層面互斥,通過jvm層面實現,不但可以通過監控工具監控synchronized的鎖定,當代碼執行出現異常時,jvm會自動釋放鎖,而lock就不行;Lock是一個接口,java jDK 1.5之後推出的api層面互斥,lock通過代碼來實現要保證鎖一定會被釋放,必須放在lock ,unlock,try/catch/finnally語句中。

 Lock可以讓等待鎖的線程中斷(主要使用Reentranlock重入鎖),去幹別的事,而synchronized就不行,使用synchronized時,線程會一直等待下去,不能夠響應中斷。

使用lock可以知道是否獲取鎖,而synchronized無法辦到。(可以使用trylock方法返回值true(獲取鎖) 或 false(沒有獲取鎖))

lock可以提高多線程進行操作(主要使用ReadWriterLock讀寫鎖)的效率。(例如lock可以實現多線程讀線程間不發生衝突,而synchronized不能多線程同時讀

在性能上來說,如果競爭資源不激烈,兩者的性能是差不多的,而當競爭資源非常激烈時(即有大量線程同時競爭),此時Lock的性能要遠遠優於synchronized。所以說,在具體使用時要根據適當情況選擇。

舉個例子:當有多個線程讀寫文件時,讀操作和寫操作會發生衝突現象,寫操作和寫操作會發生衝突現象,但是讀操作和讀操作不會發生衝突現象。

  但是採用synchronized關鍵字來實現同步的話,就會導致一個問題:

  如果多個線程都只是進行讀操作,所以當一個線程在進行讀操作時,其他線程只能等待無法進行讀操作。

  因此就需要一種機制來使得多個線程都只是進行讀操作時,線程之間不會發生衝突,通過Lock就可以辦到。

  另外,通過Lock可以知道線程有沒有成功獲取到鎖。這個是synchronized無法辦到的

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