原文:http://blog.csdn.net/zheng548/article/details/54426947
區別一:API層面
syschronized使用
synchronized即可修飾方法,也可以修飾代碼塊。
synchronized修飾方法時,如下所示:
//synchronized修飾一個方法時,這個方法叫同步方法 public synchronized void test(){ //方法體 }
synchronized修飾代碼塊時,包涵兩部分:鎖對象的引用和這個鎖保護的代碼塊。如下所示:
synchronized (0bject){ //括號中表示需要鎖的對象 //線程執行時會對object上鎖 }
ReentrantLock使用
public class test(){ private Lock lock=new ReentrantLock(); public void testMethod(){ try{ lock.lock(); //code } finally{ lock.unlock(); } } }
區別二:等待可中斷
引用周志明的《深入理解Java虛擬機》Page 392
等待可中斷是指當持有鎖的線程長期不釋放鎖的時候,正在等待的線程可以選擇放棄等待,改為處理其他事情。可等待特性對處理執行時間非常長的同步塊很有幫助。
具體說來,假如業務代碼中有兩個線程,Thread1 Thread2.假設Thread1獲取了對象object的鎖,Thread2將等待Thread1釋放object的鎖。
-
使用synchronized。如果Thread1不釋放,Thread2將一直等待,不能被中斷。synchronized也可以說是Java提供的原子性內置鎖機制。內部鎖扮演了互斥鎖(mutual exclusion lock ,mutex)的角色,一個線程引用鎖的時候,別的線程阻塞等待。
-
使用ReentrantLock。如果Thread1不釋放,Thread2等待了很長時間以后,可以中斷等待,轉而去做別的事情。
區別三:公平鎖
引用周志明的《深入理解Java虛擬機》Page 392
公平鎖是指多個線程在等待同一個鎖時,必須按照申請的時間順序來依次獲得鎖;而非公平鎖則不能保證這一點。非公平鎖在鎖被釋放時,任何一個等待鎖的線程都有機會獲得鎖。 synchronized的鎖是非公平鎖,ReentrantLock默認情況下也是非公平鎖,但可以通過帶布爾值的構造函數要求使用公平鎖。
區別四:綁定多個條件
ReentrantLock可以同時綁定多個Condition對象,只需多次調用newCondition方法即可。
synchronized中,鎖對象的wait和notify() 或notifyAll()方法可以實現一個隱含的條件。但如果要和杜宇一個的條件關聯的時候就不得不額外添加一個鎖。
區別五:性能
JDK 1.5中,synchronized還有很大的優化余地。JDK 1.6 中加入了很多針對鎖的優化措施,synchronized與ReentrantLock性能方面基本持平。虛擬機在未來的改進中更偏向於原生的synchronized。
補充:
①Java中每個對象都有一個鎖(lock)或者叫做監視器(monitor).
②ReentrantLock和synchronized持有的對象監視器不同。
③如果synchronized方法是static的,那么當線程方法改方法時,它鎖的並不是synchronized方法所在的對象,而是synchronized方法所在對象所對應的class對象,因為java中不管一個類有多少對象,這些對象會應對唯一一個Class對象。因此當線程分別訪問同一個類的兩個對象的兩個static,synchronized方法時,是順序執行的,即一個線程先執行,另一個才開始。
④synchronized方法是一種粗粒度的並發控制,某一時刻只能有一個線程執行synchronized方法,synchronized快則是一種細粒度的並發控制。只會將 塊中代碼同步,位於方法內,synchronized塊之外的是可以被多個線程同時訪問的。
⑤synchronized關鍵字經過編譯之后,會在同步塊的前后分別形成monitorenter和monitorexit兩個字節碼指令,操作對象均為鎖的計數器。
⑥相同點:都是可重入的。可重入值的是同一個線程多次試圖獲取它所占的鎖,請求會成功。當釋放的時候,直到沖入次數清零,鎖才釋放。