对于Lock与synchronized的区别
1、Lock能够完成synchronized所实现的所有功能,并且提供了多样化的同步,比如有时间限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。
- 如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断。
- 如果使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情。
2、synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定。但Lock不能,只能手动释放,并且在finally从句中unLock()释放。
3、性能:
在jdk1.5中Synchronized是使用的独占悲观锁,资源竞争不激烈的情况下synchronized性能略高,资源竞争激烈 的情况下性能要远低于Lock。jdk1.6以后synchronized和lock一样都是使用CAS乐观锁操作,所以性能差不多,对于具体使用哪一个 要看具体的系统应用需要,Synchronized相对简单易用,若需要精细的灵活控制则可以考虑选择lock。
- void lock(); ---获取锁。执行此方法时,如果锁处于空闲状态,当前线程将获取到锁。相反,如果锁已经被其他线程持有,将禁用当前线程并处于休眠状态,直到当前线程获取到锁。
- void unlock(); ----执行此方法时,当前线程将释放持有的锁。锁只能由持有者释放,如果线程并不持有锁,却执行该方法,可能导致异常的发生。
- boolean tryLock(); ----如果锁可用, 则获取锁, 并立即返回true, 否则返回false. 该方法和lock()的 区别在于, tryLock()只是"试图"获取锁, 如果锁不可用, 不会导致当前线程被禁用,当前线程仍然继续往下执行代码. 而lock()方法则是一定要获取到锁, 如果锁不可用, 就一直等待, 在未获得锁之前,当前线程并不继续向下执行. 通常采用如下的代码形式调用tryLock()方法:
- void lockInterruptibly() throws InterruptedException; ----如果当前线程未被中断且可用,则获取锁并立即返回。 如果锁不可用,将禁用当前线程,并且在发生以下两种情况之一以前,该线程将一直处于休眠状态:
Ø 锁由当前线程获得;或者
Ø 其他某个线程中断当前线程,并且支持对锁获取的中断
Synchronized内部锁,可以在线程转储时,记录哪些调用框架获得了哪些锁,并能够识别发生死锁的线程。但jvm不知道哪些线程持有重入锁。这个问题在JDK6中得到解决。
Synchronized只支持不公平锁,Lock可以支持支持公平锁和非公平锁。