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提供了多种基于锁的处理机制,比如:
- void lock(),获取一个锁,如果锁当前被其他线程获得,当前的线程将被休眠。
- boolean tryLock(),尝试获取一个锁,如果当前锁被其他线程持有,则返回false,不会使当前线程休眠。
- boolean tryLock(long timeout,TimeUnit unit),如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false。
- 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语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
java 运行报错has been compiled by a more recent version of the Java Runtime
java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01- 这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
- 这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
- 说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
- 这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
- 这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
- 这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
java 画pdf用itext调整表格宽度、自定义各个列宽的方法
这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31- 这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
Java使用ScriptEngine动态执行代码(附Java几种动态执行代码比较)
这篇文章主要介绍了Java使用ScriptEngine动态执行代码,并且分享Java几种动态执行代码比较,需要的朋友可以参考下...2021-04-15- 这篇文章主要介绍了Java开发实现人机猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-03
- 这篇文章主要介绍了Java List集合返回值去掉中括号('[ ]')的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-29
Java中lombok的@Builder注解的解析与简单使用详解
这篇文章主要介绍了Java中lombok的@Builder注解的解析与简单使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-06- 下面小编就为大家带来一篇java中String类型变量的赋值问题介绍。小编觉得挺不错的。现在分享给大家,给大家一个参考。...2016-03-28
Java 8 Stream 的终极技巧——Collectors 功能与操作方法详解
这篇文章主要介绍了Java 8 Stream Collectors 功能与操作方法,结合实例形式详细分析了Java 8 Stream Collectors 功能、操作方法及相关注意事项,需要的朋友可以参考下...2020-05-20- 这篇文章主要介绍了Java线程池中的各个参数如何合理设置操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-19
- 在Java中,我们可以利用多线程来最大化地压榨CPU多核计算的能力,下面这篇文章主要给大家介绍了关于java中多线程与线程池基本使用的相关资料,需要的朋友可以参考下...2021-09-13