synchronized 和 ReentrantLock 的区别
synchronized 和 ReentrantLock 的区别
synchronized 的特点
synchronized 修饰的方法或者代码块在同一时刻,只能有一个线程在执行对应的代码逻辑。synchronized 可以使用到方法声明上,也可以使用在代码块上,当运行到对应被 synchronized 修饰的代码块时,线程会先检查是否有别的线程正在执行同步代码块,如果没有的话,会直接运行,如果有的话,线程会阻塞等待,等到其他线程执行完成后,再重新进行检查,判断是否能够执行相应的代码逻辑。
synchronized 拥有可重入性,一个线程拿到对象对应锁的持有权后,可以再次请求对象内的其他 synchronized 方法的,这代表在执行 synchronized 方法时,调用当前对象的其他 synchronized 方法也是可以得到锁执行逻辑的。相反的,如果不具备可重入性,那么当线程获取对象锁之后,再执行对象的其他 synchronized 方法时,由于自身已经持有了对象锁,此时就会造成死锁的现象。
synchronized 对任意对象加锁时,只需使用关键字 synchronized 修饰即可,锁的释放 JAVA 会自动执行,即使出现异常,JAVA 也会自动 释放锁。
ReentrantLock 的特点
ReentrantLock 通常称作可重入锁,顾名思义,和 synchronized 一样,也是具有可重入性的。
ReentrantLock 对对象加锁时,需要显示的调用 lock()方法,释放锁时,也需要显示的调用 unlock 方法,并且 ReentrantLock 可以自定义为公平锁或者是非公平锁。
ReentrantLock 在出现异常时,并不会有自动释放锁的机制,此时会产生一直持有锁对象无法释放的情况,所以在实际的使用中,最好是结合 try-catch 一起使用。
总结
synchronized 相对于 ReentrantLock 来说,使用相对简单,但是 synchronized 内部有锁升级的机制,所以在高并发情况下,synchronized 的锁升级(最后升级为重量级锁),会导致效率变低。
synchronized 可以自动释放锁,ReentrantLock 必须手动释放锁。
ReentrantLock 可以定义公平或者非公平锁,synchronized 是非公平锁。
版权声明: 本文为 InfoQ 作者【zarmnosaj】的原创文章。
原文链接:【http://xie.infoq.cn/article/4065587a15a43f3ec242f7f54】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论