欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

synchronized 和 ReentrantLock区别

程序员文章站 2022-06-15 16:33:34
...

一.sychronized

sychronized是java中最基本同步互斥的手段,可以修饰代码块、方法、类。 在修饰代码块的时候需要一个reference对象作为锁的对象。 在修饰方法的时候默认是当前对象作为锁的对象, 在修饰类时候默认是当前类的Class对象作为锁的对象。

synchronized会在进入同步块的前后分别形成monitorenter和monitorexit字节码指令。在执行monitorenter指令时会尝试获取对象的锁,如果此没对象没有被锁,或者此对象已经被当前线程锁住,那么锁的计数器加一,每当monitorexit被锁的对象的计数器减一,直到为0就释放该对象的锁。由此synchronized是可重入的,不会出现自己把自己锁死。

二.ReentrantLock

以对象的方式来操作对象锁.相对于sychronized需要在finally中去释放锁

三.synchronized和ReentrantLock的区别

除了synchronized的功能,多了三个高级功能: 等待可中断、公平锁、绑定多个Condition。

1.等待可中断

在持有锁的线程长时间不释放锁的时候,等待的线程可以选择放弃等待。

tryLock(long timeout, TimeUnit unit)

2.公平锁

按照申请锁的顺序来一次获得锁称为公平锁。synchronized的是非公平锁,ReentrantLock可以通过构造函数实现公平锁。

new RenentrantLock(boolean fair)

3.绑定多个Condition

通过多次newCondition可以获得多个Condition对象,可以简单的实现比较复杂的线程同步的功能。通过await(),signal();

总的来说,lock更加灵活。

主要相同点:

Lock能完成synchronized所实现的所有功能

不同点:

1.ReentrantLock功能性方面更全面,比如时间锁等候,可中断锁等候,锁投票等,因此更有扩展性。在多个条件变量和高度竞争锁的地方,用ReentrantLock更合适,ReentrantLock还提供了Condition,对线程的等待和唤醒等操作更加灵活,一个ReentrantLock可以有多个Condition实例,所以更有扩展性。

2.ReentrantLock必须在finally中释放锁,否则后果很严重,编码角度来说使用synchronized更加简单,不容易遗漏或者出错。

3.ReentrantLock 的性能比synchronized会好点。

4.ReentrantLock提供了可轮询的锁请求,他可以尝试的去取得锁,如果取得成功则继续处理,取得不成功,可以等下次运行的时候处理,所以不容易产生死锁,而synchronized则一旦进入锁请求要么成功,要么一直阻塞,所以更容易产生死锁。