显式锁:Lock接口

284 阅读2分钟

显式锁Lock

锁是用来控制多个线程访问共享资源的方式,在Lock接口出现之前,Java程序用我们所熟知的synchronized关键字来实现锁功能。synchronized是隐式锁,而Lock接口则是显式锁,隐式锁与显式锁的区别简单来说就是需不需要手动写代码去释放锁,需要的话就是显式锁,不需要的话就是隐式锁。

//隐式锁
synchronized(锁对象){
   //任务代码
}
​
//显示锁
Lock l = new ReentrantLock()
   @Override
   public void run(){
   l.lock;
       //任务代码
       try{
       
      }finaly{
           l.unlock;
      }
  }
​

Lock接口虽然少了隐式获取和释放锁的便利性,但是却拥有了锁获取和释放的可操作性、可中断的获取锁和超时获取锁等多种synchronized关键字所不具备的同步性能。

我们举例一个场景,使用手动操作显式获取和释放锁:先获取到了锁A,然后再去获取锁B,当锁B获取到了就释放锁A,再去获取锁C,当C获取到了同时释放锁B和去获取锁D。显然隐式锁做不到这点

Lock的使用很简单,如下

 Lock lock = new ReentrantLock();
       lock.lock();
       try {
           //你的业务代码
      }finally {
           lock.unlock();
      }

在finally块中释放锁,目的就是保证获取到锁之后,最终能够被释放,记住不要将释放锁放在try代码块中,因为如果发生异常,try代码块中的释放锁可能不会被执行,导致锁得不到释放。

此外,Lock锁还具备synchronized关键字所不具备的主要特性,如下

  1. 尝试非阻塞地获取锁 : 当前线程尝试获取锁,当锁获得后,从该方法返回
  2. 能够被中断地获取锁:可中断地获取锁,和lock()方法的不同之处在于该方法会响应中断,即在锁的获取中可以中断当前线程。
  3. 超时获取锁:在指定的截止时间获取锁,如果截止时间到了仍旧无法获取锁,则返回。