lock lockJava中Lock,tryLock,lockInterruptibly有什么区别

lock lock  时间:2022-03-01  阅读:()

Java中Lock,tryLock,lockInterruptibly有什么区别

ReentrantLock 锁有好几种,除了常用的lock ,tryLock ,其中有个lockInterruptibly 。 先把API粘贴上来 lock public void lock() 获取锁。 如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为 1。 如果当前线程已经保持该锁,则将保持计数加 1,并且该方法立即返回。 如果该锁被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁之前,该线程将一 直处于休眠状态,此时锁保持计数被设置为 1。 指定者: 接口 Lock 中的 lock lockInterruptibly public void lockInterruptibly() throws InterruptedException 1)如果当前线程未被中断,则获取锁。 2)如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为 1。 3)如果当前线程已经保持此锁,则将保持计数加 1,并且该方法立即返回。 4)如果锁被另一个线程保持,则出于线程调度目的,禁用当前线程,并且在发生以下两种情况之一以 前,该线程将一直处于休眠状态: ? ? 1)锁由当前线程获得;或者 ? ? 2)其他某个线程中断当前线程。 5)如果当前线程获得该锁,则将锁保持计数设置为 1。 ? 如果当前线程: ? ? ? 1)在进入此方法时已经设置了该线程的中断状态;或者 ? ? ? 2)在等待获取锁的同时被中断。 ? 则抛出 InterruptedException,并且清除当前线程的已中断状态。 6)在此实现中,因为此方法是一个显式中断点,所以要优先考虑响应中断,而不是响应锁的普通获取或 重入获取。 指定者: 接口 Lock 中的 lockInterruptibly 抛出: ? InterruptedException ? 如果当前线程已中断。 tryLock ? ?public boolean tryLock() 仅在调用时锁未被另一个线程保持的情况下,才获取该锁。 1)如果该锁没有被另一个线程保持,并且立即返回 true 值,则将锁的保持计数设置为 1。 即使已将此锁设置为使用公平排序策略,但是调用 tryLock() 仍将 立即获取锁(如果有可用的), 而不管其他线程当前是否正在等待该锁。在某些情况下,此“闯入”行为可能很有用,即使它会打破公 平性也如此。如果希望遵守此锁的公平设置,则使用 tryLock(0, TimeUnit.SECONDS) ,它几乎是等效的(也检测中断)。 2)如果当前线程已经保持此锁,则将保持计数加 1,该方法将返回 true。 3)如果锁被另一个线程保持,则此方法将立即返回 false 值。 指定者: ? 接口 Lock 中的 ?tryLock 返回: ? 如果锁是自由的并且被当前线程获取,或者当前线程已经保持该锁,则返回 true;否则返回 false 关于中断又是一段很长的叙述,先不谈。 1)lock(), 拿不到lock就不罢休,不然线程就一直block。 比较无赖的做法。 2)tryLock(),马上返回,拿到lock就返回true,不然返回false。 比较潇洒的做法。 ? ?带时间限制的tryLock(),拿不到lock,就等一段时间,超时返回false。比较聪明的做法。 3)lockInterruptibly()就稍微难理解一些。 先说说线程的打扰机制,每个线程都有一个 打扰 标志。这里分两种情况, 1. 线程在sleep或wait,join, 此时如果别的进程调用此进程的 interrupt()方法,此线程会被唤醒并被要求处理InterruptedException;(thread在做IO操作时也可能有类似行为,见java thread api) 2. 此线程在运行中, 则不会收到提醒。但是 此线程的 “打扰标志”会被设置, 可以通过isInterrupted()查看并 作出处理。 lockInterruptibly()和上面的第一种情况是一样的, 线程在请求lock并被阻塞时,如果被interrupt,则“此线程会被唤醒并被要求处理InterruptedException”。并且如果线程已经被interrupt,再使用lockInterruptibly的时候,此线程也会被要求处理interruptedException 先看lock()方法 import?java.util.concurrent.locks.Lock; import?java.util.concurrent.locks.ReentrantLock; /** ?*?@author?作者?E-mail: ?*?@version?创建时间:2015-10-23?下午01:47:03?类说明 ?*/ public?class?TestLock { ????//?@Test ????public?void?test()?throws?Exception ????{ ????????final?Lock?lock?=?new?ReentrantLock(); ????????lock.lock(); ????????Thread?t1?=?new?Thread(new?Runnable() ????????{ ????????????@Override ????????????public?void?run() ????????????{ ????????????????lock.lock(); ????????????????System.out.println(Thread.currentThread().getName()?+?"?interrupted."); ????????????} ????????},"child?thread?-1"); ????????t1.start(); ????????Thread.sleep(1000); ????????t1.interrupt(); ????????Thread.sleep(1000000); ????} ????public?static?void?main(String[]?args)?throws?Exception ????{ ????????new?TestLock().test(); ????} } 用eclipse对这个程序进行debug发现,即使子线程已经被打断,但是子线程仍然在run,可见lock()方法并不关心线程是否被打断,甚至说主线程已经运行完毕,子线程仍然在block(). 而使用LockInterupptibly,则会响应中断 import?java.util.concurrent.locks.Lock; import?java.util.concurrent.locks.ReentrantLock; /** ?*?@author?作者?E-mail: ?*?@version?创建时间:2015-10-23?下午01:53:10?类说明 ?*/ public?class?TestLockInterruptibly { ????//?@Test ????public?void?test3()?throws?Exception ????{ ????????final?Lock?lock?=?new?ReentrantLock(); ????????lock.lock(); ????????Thread?t1?=?new?Thread(new?Runnable() ????????{ ????????????@Override ????????????public?void?run() ????????????{ ????????????????try ????????????????{ ????????????????????lock.lockInterruptibly(); ????????????????} ????????????????catch(InterruptedException?e) ????????????????{ ????????????????????System.out.println(Thread.currentThread().getName()?+?"?interrupted."); ????????????????} ????????????} ????????},?"child?thread?-1"); ????????t1.start(); ????????Thread.sleep(1000); ????????t1.interrupt(); ????????Thread.sleep(1000000); ????} ????public?static?void?main(String[]?args)?throws?Exception ????{ ????????new?TestLockInterruptibly().test3(); ????} } try{ ? ? ?Thread.sleep(2000); ? ? ?lock.lockInterruptibly(); ? }catch(InterruptedException e){ ? ? ? System.out.println(Thread.currentThread().getName()+" interrupted."); } ?t1.start(); ?t1.interrupt(); ?Thread.sleep(1000000); 如果将代码改成这样,那么将会在在阻塞之前已经中断,此时再lockInterruptibly()也是会相应中断异常的

妮妮云香港CTG云服务器1核 1G 3M19元/月

香港ctg云服务器香港ctg云服务器官网链接 点击进入妮妮云官网优惠活动 香港CTG云服务器地区CPU内存硬盘带宽IP价格购买地址香港1核1G20G3M5个19元/月点击购买香港2核2G30G5M10个40元/月点击购买香港2核2G40G5M20个450元/月点击购买香港4核4G50G6M30个80元/月点击购买香...

3G流量免费高防CDN 50-200G防御

简介酷盾安全怎么样?酷盾安全,隶属于云南酷番云计算有限公司,主要提供高防CDN服务,高防服务器等,分为中国境内CDN,和境外CDN和二个产品,均支持SSL。目前CDN处于内测阶段,目前是免费的,套餐包0.01一个。3G流量(高防CDN)用完了继续续费或者购买升级包即可。有兴趣的可以看看,需要实名的。官方网站: :点击进入官网云南酷番云计算有限公司优惠方案流量3G,用完了不够再次购买或者升级套餐流量...

选择Vultr VPS主机不支持支付宝付款的解决方案

在刚才更新Vultr 新年福利文章的时候突然想到前几天有网友问到自己有在Vultr 注册账户的时候无法用支付宝付款的问题,当时有帮助他给予解决,这里正好顺带一并介绍整理出来。毕竟对于来说,虽然使用的服务器不多,但是至少是见过世面的,大大小小商家的一些特性特征还是比较清楚的。在这篇文章中,和大家分享如果我们有在Vultr新注册账户或者充值购买云服务器的时候,不支持支付宝付款的原因。毕竟我们是知道的,...

lock lock为你推荐
java队列怎样用java代码实现一个队列资源优化配置资源优化配置的前提条件网络限速软件有什么比较好的网络限速的软件硬盘分区格式化电脑硬盘怎么全部格式化并重新分区?教学视频网站谁有各种教学视频网站呀.?网络购物的发展网购未来的发展趋势如何?sd卡座sd卡座使用过程中需注意哪些事项海淀区公司注册注册海淀公司需要验资报告吗fshow神禧年是什么?e游一般的动漫游戏中,EX是什么意思
过期域名查询 免费vps 如何查询域名备案号 免费动态域名解析 域名停靠一青草视频 什么是二级域名 淘宝抢红包攻略 dns是什么 buyvm stablehost softlayer omnis 2017年万圣节 地址大全 魔兽世界台湾服务器 本网站服务器在美国 本网站在美国维护 nerds 上海服务器 香港亚马逊 更多