Lock 接口与 synchronized 关键字的区别

 

      

拷贝别的博主总结的9点不同:

1.JDK版本不同

synchronized关键字产生于JKD1.5之前,是低版本保证共享资源同步访问的主要技术。
Lock接口产生于JDK1.5版本,位于著名的java.util.concurrent并发包中,是Java提供的一种比synchronized关键字更加灵活与丰富的共享资源同步访问技术。


2.读写锁

synchronized关键字只提供了一种锁,即独占锁。
Lock接口不仅提供了与前者类似的独占锁,而且还通过ReadWriteLock接口提供了读锁和写锁。
读写锁最大的优势在于读锁与读锁并不独占,提高了共享资源的使用效率。


3.块锁与链锁

synchronized关键字以代码块或者说是作用域机制实现了加锁与解锁,我简称为块锁。synchronized关键字的作用域机制导致同步块必须包含在同一方法中,且多个锁的加锁与解锁顺序正好相反,即:{{{}}}结构。
Lock接口并不限制锁的作用域和加解锁次序,可以提供类似于链表样式的锁,所以我简称为链锁。Lock接口并不需要把加锁和解锁方法放在同一方法中,且加锁和解锁顺序完全随意,即:{{}{}}结构。


4.解锁方式

synchronized关键字:随着同步块/方法执行完毕,自动解锁。
Lock接口:需要手动通过lock.unlock()方法解锁,一般此操作位于finally{}中。

扫描二维码关注公众号,回复: 10896898 查看本文章


5.阻塞锁与非阻塞锁

synchronized关键字提供的锁是阻塞的,它会一直尝试通过轮询去获取对象的监视锁。
Lock接口通过lock.tryLock()方法提供了一种非阻塞的锁,它会尝试去获取锁,如果没有获取锁,则不再尝试。


6.可中断锁

synchronized关键字提供的锁是不可中断的,它会一直尝试去获取锁,我们无法手动的中断它。
Lock接口通过lock.lockInterruptibly()提供了一种可中断的锁,我们可以主动的去中断这个锁,避免死锁的发生。


7.可超时锁

synchronized关键字提供的锁是不可超时的,它会一直尝试去获取锁,直至获取锁。
Lock接口通过{tryLock(long, TimeUnit)方法}方法提供了一种可超时的锁,它会在一段时间内尝试去获取锁,如果限定时间超时,则不再尝试去获取锁,避免死锁的发生。


8.公平锁(线程次序保证)

我们都知道,如果高并发环境下多个线程尝试去访问同一共享资源,同一时刻只有一个线程拥有访问这个共享资源的锁,其他的线程都在等待。

synchronized关键字提供的锁是非公平锁,如果持有锁的线程释放了锁,则新进入的线程与早就等待的线程拥有同样的机会获取这个锁,简单来说就是不讲究:先来后到,反而讲究:来得早不如来得巧。非公平锁可能导致某些线程永远都不会获取锁。
Lock接口默认也是非公平锁,但是他还可以通过fair参数指定为公平锁。在公平锁机制下,等待的线程都会被标记等待次数,等待次数越多的锁获取锁的优先级越高,也就是常说的:先到先得。


9.互不干扰、可以共用

synchronized关键字是通过关键字实现对对象的加锁与解锁的。
Lock接口是通过Lock接口的实现类的实例对象的lock()和unlock()方法实现加锁与解锁的。
我们也可以通过synchronized关键字对Lock接口的实现类的实例对象进行监视器锁的加锁与解锁。而且对监视器锁的加锁与解锁与Lock接口的实现类的实例对象的lock()和unlock()方法并不冲突。
也就是说我们可以同时使用Lock接口和synchronized关键字实现同步访问控制。
但是,原则上是极其不建议这种混搭的同步访问控制方式的,不仅代码难以阅读,而且容易出错。
 

发布了138 篇原创文章 · 获赞 22 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/guihaiyuan123/article/details/105567512