主要区别
1、Lock能完成几乎所有synchronized的功能,并有一些后者不具备的功能,如公平锁、等待可中断、锁绑定多个条件等;
2、synchronized 是Java 语言层面的,是内置的关键字;Lock 则是JDK 5中出现的一个包,在使用时,synchronized 同步的代码块可以由JVM自动释放;Lock需要程序员在finally块中手工释放,如果不释放,可能会引起难以预料的后果。
重入锁
java.util.concurrent.lock
中的 Lock
框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现。这就为 Lock
的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。ReentrantLock
类实现了Lock
,它拥有与 synchronized
相同的并发性和内存语义。
实现原理:它有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,那么获取计数器就加1,然后锁需要被释放两次才能获得真正释放,原理上模仿了 synchronized
的语义。
总结
很多人都知道重入锁的性能高于synchronized,其实这个是停留在JDK1.5的阶段,在JDK到1.6的时候引入了许多针对synchronized的优化措施,如自旋锁、轻量级锁、偏向锁等,性能上也基本和重入锁持平了。个人觉得如果用不到重入锁的一些特殊的功能尽量不要用重入锁,原因主要有三个方面:
1、毕竟大部分开发者对synchronized的熟悉远远超过重入锁且重入锁需要手动释放锁,如果一旦忘记释放就很悲剧了;
2、如果使用synchronized,发生线程阻塞这些问题的时候通过thread dump比较容易看出来;
3、synchronized毕竟是JVM语义级别的,以后的肯恩会更多的针对这部分做性能优化。