- 1、本文档共3页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
本文由简悦SimpRead转码,原文地址
本我们主要学习synchronized和Lock的异同点,以及该如何选择。
相同点
synchronized和Lock的相同点非常多,我们这里重点讲解3个比较大的相同点。
synchronized和Lock都是用来保护资源线程安全的。
这一点毋庸置疑,这是它们的基本作用。
都可以保证可见性。
对于synchronized而言,线程A在进入synchronized块之前或在synchronized块内进行操作,对于
后续的获得同一个monitor锁的线程B是可见的,也就是线程B是可以看到线程A之前的操作的,这
也体现了happens-before针对synchronized的一个原则。
而对于Lock而言,它和synchronized是一样,都可以保证可见性,如图所示,在之前的所有操
作对加锁的所有操作都是可见的。
如果你之前不了解什么是可见性,此时理解可能会有一定的,可以在学习本专栏的Java内存模型
相关内容后,再复习本,就会豁然开朗。
synchronized和ReentrantLock都拥有可重入的特点。
这里的ReentrantLock是Lock接口的一个最主要的实现类,在对比synchronized和Lock的时候,也
会选择Lock的主要实现类来进行对比。可重入指的是某个线程如果已经获得了一个锁,现在试图再次
请求这个它已经获得的锁,如果它无需提前释放这个锁,而是直接可以继续使用持有的这个锁,那么就
是可重入的。如果必须释放锁后才能再次申请这个锁,就是不可重入的。而synchronized和
ReentrantLock都具有可重入的特性。
不同点
下面我们来看下synchronized和Lock的区别,和相同点一样,它们之间也有非常多的区别,这里讲
解其中比较大的7点不同。
用法区别
synchronized关键字可以加在方法上,不需要指定锁对象(此时的锁对象为this),也可以新建一个
同步代码块并且自定义monitor锁对象;而Lock接口必须显示用Lock锁对象开始加锁lock()和
unlock(),并且一般会在finally块中确保用unlock()来,以防发生死锁。
与Lock显式的加锁和不同的是synchronized的加是隐式的,尤其是抛异常的时候也能保证
释放锁,但是Java代码中并没有相关的体现。
加顺序不同
对于Lock而言如果有多把Lock锁,Lock可以不完全按照加锁的反序,比如我们可以先获取
Lock1锁,再获取Lock2锁,时则先Lock1,再Lock2,加有一定的灵活度,如代码
所示。
lock1.lock();
lock2.lock();
...
lock1.unlock();
lock2.unlock();
但是synchronized无法做到,synchronized的顺序和加锁的顺序必须完全相反,例如:
synchronized(obj1){
synchronized(obj2){
...
}
}
那么在这里,顺序就是先对obj1加锁,然后对obj2加锁,然后对obj2,最后obj1。这是因
为synchronized加是由JVM实现的,在执行完synchronized块后会自动,所以会按照
synchronized的嵌套顺序加,不能自行控制。
synchronized锁不够灵活
一旦synchronized锁已经被某个线程获得了,此时其他线程如果还想获得,那它只能被阻塞,直到持
有锁的线程运行完毕或者发生异常从而释放这个锁。如果持有锁的线程持有很长时间才释放,那么整个
程序的运行效率就会降低,而且如果持有锁的线程不释放锁,那么尝试获取锁的线程只能等下
去。
相比之下,Lock类在等锁的过程中,如果使用的是lockInterruptibly方法,那么如果觉得等待的时间
文档评论(0)