1、區別:
1)Lock是一個接口,synchronized是Java中的關鍵字,synchronized是內置的語言實現;
2)synchronized發生異常時,會自動釋放線程占用的鎖,故不會發生死鎖現象。Lock發生異常,若沒有主動釋放,極有可能造成死鎖,故需要在finally中調用unLock方法釋放鎖;
3)Lock可以讓等待鎖的線程響應中斷,使用synchronized只會讓等待的線程一直等待下去,不能響應中斷
4)通過Lock可以知道有沒有成功獲取到鎖,synchronized就不靈
5)Lock可以提高多個線程進行讀操作的效率
2、在鎖概念上的區別:
1)可中斷鎖
響應中斷的鎖,Lock是可中斷鎖(體現在lockInterruptibly()方法),synchronized不是。如果線程A正在執行鎖中代碼,線程B正在等待獲取該鎖。時間太長,線程B不想等了,可以讓它中斷自己。
也可設置超時時間:tryLock(long timeout,TimeUnit unit);
2)公平鎖
盡量以請求鎖的順序獲取鎖。比如同時有多個線程在等待一個鎖,當鎖被釋放后,等待時間最長的獲取該鎖,跟京牌司法拍賣一個道理。非公平鎖可能會導致有些線程永遠得不到鎖,synchronized是非公平鎖,ReentrantLock默認非公平鎖,構造方法可以傳入布爾值,true為公平鎖,false為非公平鎖。
3)讀寫鎖
讀寫鎖將對一個資源(如文件)的訪問分為2個鎖,一個讀鎖,一個寫鎖;讀寫鎖使得多個線程的讀操作可以並發進行,不需同步。而寫操作就得需要同步,提高了效率,ReadWriteLock就是讀寫鎖,是一個接口,ReentrantReadWriteLock實現了這個接口。可通過readLock()獲取讀鎖,writeLock()獲取寫鎖
4)綁定多個條件
一個ReentrantLock可以綁定多個Condition對象,僅需多次調用new Condition()即可;而在synchronized中鎖鎖對象的wait()、notify()/notifyAll()可以實現一個隱含的條件,如果要和多余的條件關聯,就不得不額外的增加一個鎖。所以ReentrantLock可以用來實現分組喚醒需要喚醒的線程們,可以精確喚醒,而不是像synchronized隨機喚醒一個或者全部喚醒
5)釋放鎖方式的區別
synchronized不需要用戶手動釋放鎖,synchronized代碼塊執行完或拋異常會自動讓線程釋放鎖;而ReentrantLock則需要用戶手動去釋放鎖,否則可能出現死鎖。一般lock和unlock方法配置在try/finally語句塊。
3、性能比較:
大量線程同時競爭,ReentrantLock要遠勝於synchronized。
JDK5中,synchronized是性能低效的,因為這是一個重量級操作,對性能的最大影響是阻塞的實現,掛起線程和恢復線程的操作,都需要轉入內核態中完成,給並發帶來了很大壓力。
JDK6中synchronized加入了自適應自旋、鎖消除、鎖粗化、輕量級鎖、偏向鎖等一系列優化,官方也支持synchronized,提倡在synchronized能實現需求的前提下,優先考慮synchronized來進行同步。