相同

  • 都是阻塞加锁
  • 都是可重入锁

区别

API方面

  1. Synchronized是java关键字,属于原生语法的互斥,需要jvm实现
  2. ReentrantLock是API层面的互斥,使用lock+unlock以及try-finally进行实现

    修饰的范围

    synchronized既可以修饰方法,也可以修饰代码块,ReentrantLock只能修饰方法块

    等待的时间

    如果等待的时间过长,那么ReentrantLock等待的线程可以选择中断等待;Synchronized只能一致等待下去

    公平性

    公平锁

  3. 按照申请的时间顺序来依次获得锁

  4. ReentrantLock可以使用公平锁

    灵活性

  • ReentrantLock可以同时绑定多个Condition,只需要多次调用newCondition就可以了。
  • synchronized关键字就相当于整个 Lock对象中只有一个Condition实例,所有的线程都注册在它一个身上。

线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活。 在使用notify()/notifyAll()方法进行通知时,被通知的线程是由 JVM 选择的。 ReentrantLock类结合Condition实例可以实现“选择性通知”** ,这个功能非常重要,而且是 Condition 接口默认提供的。 而synchronized关键字就相当于整个 Lock 对象中只有一个Condition实例,所有的线程都注册在它一个身上。 如果执行notifyAll()方法的话就会通知所有处于等待状态的线程这样会造成很大的效率问题,而Condition实例的signalAll()方法 只会唤醒注册在该Condition实例中的所有等待线程。