synchronized与ReentrantLock的区别

synchronized是Java原语,提供了互斥的语义和可见性,当一个线程已经获取了当前的锁时,其他试图获取锁的线程就只能等待或者阻塞。

ReentrantLock是实现了Lock接口,是一个互斥的同步器。当一个线程试图获取一个它已经获取的锁时,这个获取动作自动成功。

在基本用法上,synchronized与ReentrantLock很是类似,都是可重入锁,不过ReentrantLock是API层面上的互斥锁(lock()与unlock()方法配合着try/finally语句块一起使用),synchronized则是原生语法层面上的互斥锁。Lock只适用于代码块锁,而synchronized可以修饰方法、代码块。

ReentrantLock加了一些高级功能

  • 等待可中断:当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。对处理时间非常长的同步块有很大的帮助
  • 可实现公平锁:什么是公平锁?公平锁是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁;而非公平锁则不能保证这一点,在锁被释放的时候,任何一个等待锁的线程都会有机会去获得这个锁。synchronized锁是非公平锁
  • 锁可以绑定多个条件:一个ReentrantLock对象可以绑定多个Condition对象,而在synchronized中,锁对象的wait()和notify()或者notifyAll()方法可以实现一个隐含的条件,如果要和多于一个的条件关联的时候则需要再加一个锁。

注意事项

在使用ReentrantLock类时,不要将lock()放在try块中,因为 如果在获取锁的时候发生了异常,异常抛出的时候锁也会释放。

在finally中释放锁,这样不论怎么样,都会释放锁。

ReentrantLock有一个newCondition的方法,可以让用户在同一锁的情况下根据不同的情况执行等待或者唤醒的操作

你可能感兴趣的:(Java)