java并发编程专题(四)----浅谈(JUC)Lock锁

 更新时间:2020年06月30日 15:31:54   作者:rickiyang  
这篇文章主要介绍了java并发编程(JUC)Lock锁的相关内容,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下

首先我们来回忆一下上一节讲过的synchronized关键字,该关键字用于给代码段或方法加锁,使得某一时刻它修饰的方法或代码段只能被一个线程访问。那么试想,当我们遇到这样的情况:当synchronized修饰的方法或代码段因为某种原因(IO异常或是sleep方法)被阻塞了,但是锁有没有被释放,那么其他线程除了等待以外什么事都做不了。当我们遇到这种情况该怎么办呢?我们今天讲到的Lock锁将有机会为此行使他的职责。

1.为什么需要Lock

synchronized 是Java 语言层面的,是内置的关键字;Lock 则是JDK 5 的J.U.C(java/util/currrent)包中出现的一个类,在使用时,synchronized 同步的代码块可以由JVM自动释放;Lock 需要程序员在finally块中手工释放;synchronized是比较古老的实现机制,设计较早,有一些功能上的限制:

——它无法中断一个正在等候获得锁的线程

——也无法通过投票得到锁,如果不想等下去,也就没法得到锁。

——同步还要求锁的释放只能在与获得锁所在的堆栈帧相同的堆栈帧中进行

而且对多线程环境中,使用synchronized后,线程要么获得锁,执行相应的代码,要么无法获得锁处于等待状态,对于锁的处理不灵活。而Lock提供了多种基于锁的处理机制,比如:

  1. void lock(),获取一个锁,如果锁当前被其他线程获得,当前的线程将被休眠。
  2. boolean tryLock(),尝试获取一个锁,如果当前锁被其他线程持有,则返回false,不会使当前线程休眠。
  3. boolean tryLock(long timeout,TimeUnit unit),如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false。
  4. void lockInterruptibly(),如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断。

可见lock比synchronized提供了更细的粒度、更灵活的控制。

2.初探Lock

在jdk1.5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,其实真正的实现Lock接口的类就三个,ReentrantLock和ReentrantReadWriteLock的两个内部类(ReadLock和WriteLock实现了Lock的接口),下面我们来看一下Lock的类图:

  • ReentrantLock:一个可重入的互斥锁,为lock接口的主要实现。
  • ReentrantReadWriteLock:
  • ReadWriteLock、ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。
  • Semaphore:一个计数信号量。
  • Condition:锁的关联条件,目的是允许线程获取锁并且查看等待的某一个条件是否满足。
  • CyclicBarrier:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点。

①首先我们来看一下Lock的用法:

  Lock lock = new ReentrantLock();
  lock.lock();
  try{
  //处理任务
  }catch(Exception ex){

  }finally{
  lock.unlock();  //释放锁
  }

正常使用Lock的用法最多就是这样,ReentrantLock是Lock的实现类们也是最常使用的。如果采用Lock,必须主动去释放锁,并且在发生异常时,不会自动释放锁。因此一般来说,使用Lock必须在try{}catch{}块中进行,并在finally块释放锁,以保证锁一定被被释放,防止死锁的发生。

②我们也可以这样使用Lock:

Lock lock = new ReentrantLock();
  if(lock.tryLock()) {
     try{
       //处理任务
     }catch(Exception ex){

     }finally{
       lock.unlock();  //释放锁
     } 
  }else {
    //如果不能获取锁,则直接做其他事情  
  }

tryLock()方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取)则返回false,也就说这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。

这一节我们简单了解一下Lock接口,由于Lock锁的内容实在是太多,包括互斥锁,公平锁,非公平锁,共享锁以及相关的条件机制,信号量机制等等,我会一点点的把他们都啃下来,下面才是我们的重头戏。

以上就是java并发编程专题(四)----浅谈(JUC)Lock锁的详细内容,更多关于JAVA (JUC)LOCK锁的资料请关注脚本之家其它相关文章!

相关文章

  • Spring Boot接收单个String入参的解决方法

    Spring Boot接收单个String入参的解决方法

    这篇文章主要给大家介绍了关于Spring Boot接收单个String入参的解决方法,文中通过示例代码介绍的非常详细,对大家学习或者使用spring boot具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • java中的PriorityQueue类过程详解

    java中的PriorityQueue类过程详解

    这篇文章主要介绍了java中的PriorityQueue类,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Mybatis返回插入主键id的方法

    Mybatis返回插入主键id的方法

    这篇文章主要介绍了 Mybatis返回插入主键id的方法,在文章底部给大家补充了Mybatis中insert中返回主键ID的方法,非常不错,需要的朋友可以参考下
    2017-04-04
  • 基于spring-security 401 403错误自定义处理方案

    基于spring-security 401 403错误自定义处理方案

    这篇文章主要介绍了基于spring-security 401 403错误自定义处理方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • java设计模式之中介者模式

    java设计模式之中介者模式

    这篇文章主要为大家详细介绍了java设计模式之中介者模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • java实现解析json复杂数据的方法详解

    java实现解析json复杂数据的方法详解

    这篇文章主要为大家详细介绍了java如何实现解析json复杂数据,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以学习一下
    2024-01-01
  • Java数组集合的深度复制代码实例

    Java数组集合的深度复制代码实例

    这篇文章主要介绍了Java数组集合的深度复制代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • idea报错之找不到符号:类的问题及解决

    idea报错之找不到符号:类的问题及解决

    这篇文章主要介绍了idea报错之找不到符号:类的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Springboot异常错误处理解决方案详解

    Springboot异常错误处理解决方案详解

    这篇文章主要介绍了Springboot异常错误处理解决方案详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • PowerJob的IdGenerateService工作流程源码解读

    PowerJob的IdGenerateService工作流程源码解读

    这篇文章主要为大家介绍了PowerJob的IdGenerateService工作流程源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01

最新评论