Java5.0以后除了内置锁synchronized外在concurrent包还提供了显式锁接口Lock。

何为显式?

就是显式地加锁和解锁,需要自己写代码去加锁和解锁。Synchronized是隐式加锁解锁,也就是无需自己写加锁解锁代码,进了synchronized代码块就隐式加锁,出了代码块就隐式解锁。

下图为使用显式锁保证计数结果正确的demo:

在lock和unlock之间的代码是被同步的,并且和synchronized一样具有内存可见性。

Lock除了普通的lock和unlock,相比synchronized,多了一些新特性:

1.返回是否成功获取锁的lock:Boolean tryLock()

尝试获取锁,获取成功返回true,获取失败返回false。

2.定时获取锁的lock:boolean tryLock(long timeout,
  [TimeUnit](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/TimeUnit.html "enum in java.util.concurrent") unit)
 throws [InterruptedException](https://docs.oracle.com/javase/7/docs/api/java/lang/InterruptedException.html "class in java.lang")

在指定时间内获取锁成功返回true,超时返回false。

显式锁的一些扩展特性:

1.一些特定的显式锁可以实现分段锁,比如ReentrantReadWriteLock,管理读锁和写锁,读写锁相对于synchronized这种互斥锁来说可以支持更高的并发,读锁不互斥,写锁互斥,增加吞吐量。

  1. 公平性,ReentrantLock构造函数的参数可以设置锁是公平还是非公平的,非公平性的锁不保证执行顺序,哪个线程先到就执行哪个线程。非公平锁性能>公平锁性能

  2. 锁降级,写锁降为读锁。

  3. 可重入。

Synchronized和显式锁如何选择?

Synchronized能满足需求时尽量用synchronized,减少代码复杂度和忘记解锁的风险。

当synchronized满足不了需求,需要用到一些新特性比如分段锁,公平性调整等特性时,可以考虑用显式锁。

01-22 15:49