1、synchronized是关键字,就和if...else...一样,是语法层面的实现,因此synchronized获取锁以及释放锁都是Java虚拟机帮助用户完成的;ReentrantLock是类层面的实现,因此锁的获取以及锁的释放都需要用户自己去操作。特别再次提醒,ReentrantLock在lock()完了,一定要手动unlock()
2、synchronized简单,简单意味着不灵活,而ReentrantLock的锁机制给用户的使用提供了极大的灵活性。这点在Hashtable和ConcurrentHashMap中体现得淋漓尽致。synchronized一锁就锁整个Hash表,而ConcurrentHashMap则利用ReentrantLock实现了锁分离,锁的知识segment而不是整个Hash表
3、synchronized是不公平锁,而ReentrantLock可以指定锁是公平的还是非公平的
4、synchronized实现等待/通知机制通知的线程是随机的,ReentrantLock实现等待/通知机制可以有选择性地通知
5、和synchronized相比,ReentrantLock提供给用户多种方法用于锁信息的获取,比如可以知道lock是否被当前线程获取、lock被同一个线程调用了几次、lock是否被任意线程获取等等
5.1、性能不同
synchronized原始采用的是CPU悲观锁机制,在锁竞争激烈情况下,会引起CPU频繁上下文切换导致效率低。Lock用的是乐观锁方式。在竞争不是很激烈的情况下,synchronized的性能优于ReentrantLock,竞争激烈的情况下synchronized的性能会下降,而ReentrantLock则基本不变。
注:Java1.6以后对synchronized做了很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等,性能上与ReentrantLock并无太大差距。