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锁的资料请关注脚本之家其它相关文章!

相关文章

  • Java基础教程之final关键字浅析

    Java基础教程之final关键字浅析

    这篇文章主要给大家介绍了关于Java基础教程之final关键字的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • 深入浅析Spring Security5中默认密码编码器

    深入浅析Spring Security5中默认密码编码器

    这篇文章主要介绍了Spring Security5中默认密码编码器,非常不错,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-05-05
  • java 实现读取txt文本数据并以数组形式一行一行取值

    java 实现读取txt文本数据并以数组形式一行一行取值

    今天小编就为大家分享一篇java 实现读取txt文本数据并以数组形式一行一行取值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • mybatis教程之延迟加载详解

    mybatis教程之延迟加载详解

    本篇文章主要介绍了mybatis教程之延迟加载详解。详细介绍了延迟加载的意义和用法实现,有兴趣的可以了解一下
    2017-05-05
  • java.lang.OutOfMemoryError 错误整理及解决办法

    java.lang.OutOfMemoryError 错误整理及解决办法

    这篇文章主要介绍了java.lang.OutOfMemoryError 错误整理及解决办法的相关资料,需要的朋友可以参考下
    2016-10-10
  • Android内存泄漏实战解析

    Android内存泄漏实战解析

    Java是垃圾回收语言的一种。这篇文章主要介绍了Android内存泄漏 的相关资料,需要的朋友可以参考下
    2016-10-10
  • Java中指定时区的3种方法

    Java中指定时区的3种方法

    这篇文章主要介绍了Java中指定时区的3种方法,本文是一个JAVA项目和.NET项目通讯时遇到的问题,本文给出JAVA中的3种解决方法,需要的朋友可以参考下
    2015-02-02
  • java把字符串写入文件里的简单方法分享

    java把字符串写入文件里的简单方法分享

    这篇文章主要介绍了java把字符串写入到文件里的简单方法,这是跟一个外国朋友学的代码,需要的朋友可以参考下
    2014-03-03
  • Spring实战之协调作用域不同步的Bean操作示例

    Spring实战之协调作用域不同步的Bean操作示例

    这篇文章主要介绍了Spring实战之协调作用域不同步的Bean操作,结合实例形式分析了Spring协调作用域不同步的Bean相关配置及使用技巧,需要的朋友可以参考下
    2019-11-11
  • spring-cloud Sleuth的使用方法

    spring-cloud Sleuth的使用方法

    这篇文章主要介绍了spring-cloud Sleuth的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-02-02

最新评论