Synchronized和Reentrantlock的区别

ReentrantLock和Synchronized具有相同的行为与语义, 并且有更强大的功能, 如下

  1. 支持非块结构的锁, 如下这样

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    private ReentrantLock lock;

    public void foo() {
    ...
    lock.lock();
    ...
    }

    public void bar() {
    ...
    lock.unlock();
    ...
    }
  2. 支持公平与非公平锁

公平锁是线程按照FIFO的顺序来获取锁, 而非公平锁是倾向于将访问权授予等待时间最长的线程, 两者相比使用非公平锁一般具有更高的总体吞吐量

  1. 支持lock polling, 即trylock()方法, 利用该方法可以实现无锁同步, 如

    1
    2
    3
    4
    5
    while(!lock.trylock()) {
    doNothing;
    }

    doRealThing;
  2. 支持可中断锁等候(应用场景?)

  3. 支持多个条件

    1
    2
    3
    Lock lock = new ReentrantLock();
    Condition con1 = lock.newCondition();
    Condition con2 = lock.newCondition();

什么时候使用Synchronzied和ReentrantLock呢?

一般使用Synchronized就可以了, 因为Lock需要显示的去释放锁(利用finally), 这可能忘记, 而Synchronzied则由JVM来做这件事。除非要使用更高级的特性, 否则使用Synchronzied就可以了。

参考资源

  1. Why use a ReentrantLock if one can use synchronized(this)?
  2. Java theory and practice: More flexible, scalable locking in JDK 5.0