synchronized 和 ReentrantLock之间的区别

ReentrantLock为可重入互斥锁. synchronized 定位类似 , 都是用来实现互斥效果 , 保证线程安全 .

ReentrantLock的区别:

1)ReentrantLock的加锁和解锁是分开的,使用起来要手动释放锁,而sync不需要:

ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();//加锁,加锁不超过,一直阻塞等待
reentrantLock.unlock();//解锁
reentrantLock.tryLock();//加锁,加锁不成功,直接返回false或者设置等待时间。

2)ReentrantLock有两种模式,可以工作在公平锁状态下,也可以工作在非公平锁的状态下,构造方法中通过参数设定的 公平 / 非公平 模式。通过true来开启公平锁模式,默认为死锁。而synchronized无法实现公平锁。

3)ReentrantLock也有等待通知机制,搭配Condition这样的类来完成,比wait notify功能更强。可以更精确控制唤醒某个指定的线程。synchronized 是通过 Object wait / notify 实现等待-唤醒. 每次唤醒的是一个随机等待的线程.

4)synchronized 是一个关键字, JVM 内部实现的(大概率是基于 C++ 实现). ReentrantLock 是标准库的一个类, JVM 外实现的(基于 Java 实现).

5)synchronized 在申请锁失败时, 会死等. ReentrantLock 可以通过 trylock 的方式等待一段时间就 放弃.

6)  响应中断:ReentrantLock可以响应中断,而synchronized不可以。

7)  级别:ReentrantLock是API级别的锁,而synchronized是JVM级别的锁。

8)  条件绑定:ReentrantLock可以通过Condition绑定多个条件,而synchronized无法实现。

9) 并发策略:底层实现不同,syncd是同步阻塞,采用悲观并发策略;而ReentrantLock是同步非阻塞,采用乐观并发策略。

10) 锁类型:Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现。

11) 异常处理:在发生异常时,synchronized会自动释放线程占有的锁,不会导致死锁;而ReentrantLock在发生异常时,如果没有主动通过unlock()去释放锁,则可能造成死锁,因此需要在finally块中释放锁。

12) 中断响应:ReentrantLock可以让等待锁的线程响应中断,而synchronized无法做到。

13) 获取锁的结果:通过ReentrantLock可以知道是否成功获取锁,而synchronized无法做到。

14) 读操作效率:ReentrantLock可以提高多个线程进行读操作的效率,比如实现读写锁。

你可能感兴趣的:(java)