java并发编程之Lock接口

引言

锁,是java se 5之后提出的,它同synchronized关键字一样,都是用来控制多个线程对临界区访问的。

Lock与synchronized之间的区别和联系
在总结两者的区别和联系之前先引入两个概念:隐式锁显式锁

  • 隐式锁:隐式获取锁,synchronized是它的代表,使用者不需要关心其内部锁的获取和释放,所有的锁的相关操作都由具体的关键字完成;
  • 显式锁:显示地获取锁,Lock是它的代表,需要使用者在使用的时候显示地获取和释放锁。

显式锁和隐式锁都实现了对临界区访问的控制,但是显式锁提供了更灵活、更强大的接口:

  1. 隐式锁将锁的获取和释放固化了,只能先获取再释放;显式锁显然无此约束,可以按照自己的需要来做锁的释放;
  2. 显式锁提供了可中断获取锁以及超时获取锁等多种隐式锁不具备的同步特性;
  3. 提供维度更小的等待与唤醒(Condition)。

就Lock接口提供的synchronized关键字不具备的特性做一个分析描述:

特性 描述
尝试非阻塞获取锁 当前线程尝试获取锁,如果锁未被其他线程获取,当前线程成功获取并持有锁
可中断获取锁 获取锁的线程能够响应中断,当获取到锁的线程被中断时,抛出中断异常,锁被释放
超时获取锁 在指定的时间内获取锁,如果在指定的时间内未获取到,获取锁失败,返回

Lock的使用

案例1:
案例1

以读写锁为例,Lock的使用方式很简单,只需要在需要加锁的地方先获取锁,操作完成之后释放锁,需要注意的是:

  • 要在finally中释放锁,这样做的目的是保证在获取到所之后,最终都是能够被释放;
  • 不要讲获取锁的过程写在try代码块中,防止在获取锁发生异常时导致的锁无故释放。

Lock api
Lock是一个接口,定义了锁的获取和释放等基本操作。

  • void lock()
    线程调用该方法获取锁,获取锁后返回;

  • void lockInterruptibly() throws InterruptedException
    可中断地获取锁,和lock()方法的区别在于该方法可以响应中断;

  • boolean tryLock()
    尝试非阻塞获取锁,线程调用该方法后立刻返回,成功获取到锁返回true,否则返回false;

  • boolean tryLock(long time, TimeUnit unit) throws InterruptedException
    超时获取锁,该方法在以下3中情况会返回:

    1. 在超时时间内获得锁;
    2. 在超时时间被中断;
    3. 超时时间结束仍未获得,返回false。
  • void unlock()
    释放锁;

  • Condition newCondition()
    获取等待通知Condition组件,该组件和当前锁绑定,只有线程获取到了锁才能调用await()方法,调用后,当前线程释放锁。

jdk中Lock接口的实现主要包括可重入锁和读写锁,它们也都是通过AQS来完成线程的访问控制的。

猜你喜欢

转载自blog.csdn.net/u010185262/article/details/54022704