当前位置:嗨网首页>书籍在线阅读

13-在同步代码块中使用锁机制

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

2.4 在同步代码块中使用锁机制

除了 synchronized 之外,Java还提供了其他保护同步代码块的机制。其中 Lock 机制(在 java.util.concurrent.locks 包中定义了该机制)是一类比 synchronized 机制更加强大和灵活的机制。该接口目前也有了一些相应的实现(如 ReentrantLock 类)。使用 Lock 机制可以带来以下好处。

  • 构建同步代码更加灵活。关键词 synchronized 仅能作用在一段结构化代码中。通过 Lock 接口,你可以在更加复杂的代码结构下访问临界区代码。
  • 通过 Lock 接口可以获得其他由 synchronized 关键词所不能提供的功能特性,比如 tryLock() 方法。通过该方法,线程可以及时知道其他线程当前是否已经持有锁,如果当前线程尝试获取锁失败,则该方法将返回 false 。如果此时使用的是 synchronized 关键词,线程A希望执行临界区的代码,而在此同时线程B已经正在执行,那么线程A将在线程B执行完毕前保持线程挂起。如果此时使用的是 tryLock 方法,那么线程将会立即获得一个 Boolean 类型的返回值,以获知当前是否已经有其他线程在执行临界区代码。
  • 通过 ReadWriteLock 接口可以实现读写锁分离,即允许同时执行多个读锁而单个写锁与其他锁互斥。
  • Lock 接口在性能表现上比 synchronized 关键词更加优越。

ReentrantLock 类构造函数的参数中包含一个名为 fairboolean 变量,开发者可以通过该变量为锁设置不同的策略模式。若值为 false (也是默认设置)时则当前锁策略为非公平锁策略。在非公平模式下,如果有多个线程同时请求同一个锁,那么该锁将随机分配给其中的一个线程。如果该策略设置为 true ,则表示当前策略为公平锁策略。在该策略下,如果当前有多个线程在等待同一把锁,则等待时间最长的线程将获得锁。以上介绍的策略仅用于 lock()unlock() 两个方法,由于 tryLock() 方法不会使线程进入休眠状态,因此该设置不会作用在 Lock 接口的 tryLock() 方法上。

本节将告诉读者如何通过 Lock 接口及其实现类 ReentrantLock 实现临界区代码。我们将使用程序模拟一个打印队列,在这里你也将了解到公平锁的配置能给 Lock 带来怎样不同的表现。