对于 Java 来讲,锁 ( Lock ) 是一种比标准同步块 ( synchronized block ) 更灵活,更复杂的线程同步机制。
其实,Java 1.5 就已经存在 Lock 接口了。这个 Lock 接口在 java.util.concurrent.lock 包中定义,提供了大量的锁操作。
本文中,我们将讲解 Lock 接口的不同实现并介绍如何在应用程序中使用锁。
锁 ( lock ) 和同步块 ( synchronized block ) 之间的差异
使用 synchronized 块和使用 Lock API 之间几乎没有区别:
- 同步块完全包含在方法中 : 在独立的方法中,我们可以使用 Lock 提供的 lock() 和 unlock() 实现锁和解锁操作。
- 同步块不支持公平竞争,任何线程都可以获取释放的锁定,且不能指定优先级。但锁 ( Lock ) 就不一样了,可以通过指定公平属性来实现 Lock 中的公平性。这可以确保最长的等待线程被授予锁定权限。
- 如果线程无法访问同步块,则会阻塞该线程。Lock 则提供了 tryLock() 方法。线程只有在可用且不被任何其他线程保持时才获取锁定。这减少了线程等待锁定的阻塞时间。
- 处于 「 等待 」 状态以获取对同步块的访问的线程不能被中断。Lock 提供了一个 lockInterruptibly()
方法,可用于在等待锁定时中断线程。
从上面的对比来看,同步块的所有机制,锁 ( Lock ) 都有相应的 API 对应。
Lock API
我们来看看 Lock 接口提供了哪些方法: