相同
- 都是阻塞加锁
- 都是可重入锁
区别
API方面
- Synchronized是java关键字,属于原生语法的互斥,需要jvm实现
ReentrantLock是API层面的互斥,使用lock+unlock以及try-finally进行实现
修饰的范围
synchronized既可以修饰方法,也可以修饰代码块,ReentrantLock只能修饰方法块
等待的时间
如果等待的时间过长,那么ReentrantLock等待的线程可以选择中断等待;Synchronized只能一致等待下去
公平性
公平锁
按照申请的时间顺序来依次获得锁
- ReentrantLock可以使用公平锁
灵活性
ReentrantLock
可以同时绑定多个Condition
,只需要多次调用newCondition
就可以了。synchronized
关键字就相当于整个Lock
对象中只有一个Condition
实例,所有的线程都注册在它一个身上。
线程对象可以注册在指定的
Condition
中,从而可以有选择性的进行线程通知,在调度线程上更加灵活。 在使用notify()/notifyAll()
方法进行通知时,被通知的线程是由 JVM 选择的。 用ReentrantLock
类结合Condition
实例可以实现“选择性通知”** ,这个功能非常重要,而且是 Condition 接口默认提供的。 而synchronized
关键字就相当于整个 Lock 对象中只有一个Condition
实例,所有的线程都注册在它一个身上。 如果执行notifyAll()
方法的话就会通知所有处于等待状态的线程这样会造成很大的效率问题,而Condition
实例的signalAll()
方法 只会唤醒注册在该Condition
实例中的所有等待线程。