- lockInterruptibly()
- tryLock()方法
- tryLock(long time, TimeUnit unit)方法
也就是说 , 对于死锁问题,Lock能够破坏不可剥夺的条件,例如,我们下面的程序代码就破坏了死锁的不可剥夺的条件 。
public class TansferAccount{ private Lock thisLock = new ReentrantLock(); private Lock targetLock = new ReentrantLock(); //账户的余额 private Integer balance; //转账操作 public void transfer(TansferAccount target, Integer transferMoney){ boolean isThisLock = thisLock.tryLock(); if(isThisLock){ try{ boolean isTargetLock = targetLock.tryLock(); if(isTargetLock){ try{ if(this.balance >= transferMoney){ this.balance -= transferMoney; target.balance += transferMoney; } }finally{ targetLock.unlock } } }finally{ thisLock.unlock(); } } }}例外 , Lock下面有一个ReentrantLock,而ReentrantLock支持公平锁和非公平锁 。
在使用ReentrantLock的时候 , ReentrantLock中有两个构造函数,一个是无参构造函数 , 一个是传入fair参数的构造函数 。fair参数代表的是锁的公平策略,如果传入true就表示需要构造一个公平锁 , 反之则表示要构造一个非公平锁 。如下代码片段所示 。
//无参构造函数: 默认非公平锁public ReentrantLock() {sync = new NonfairSync();}//根据公平策略参数创建锁public ReentrantLock(boolean fair){sync = fair ? new FairSync() : new NonfairSync();}锁的实现在本质上都对应着一个入口等待队列,如果一个线程没有获得锁,就会进入等待队列,当有线程释放锁的时候, 就需要从等待队列中唤醒一个等待的线程 。如果是公平锁,唤醒的策略就是谁等待的时间长, 就唤醒谁 , 很公平; 如果是非公平锁,则不提供这个公平保证,有可能等待时间短的线程反而先被唤醒 。而Lock是支持公平锁的,synchronized不支持公平锁 。
最后,值得注意的是 , 在使用Lock加锁时,一定要在finally{}代码块中释放锁 , 例如,下面的代码片段所示 。
try{ lock.lock();}finally{ lock.unlock();}注:其他synchronized和Lock的详细说明 , 小伙伴们自行查阅即可 。
点击关注,第一时间了解华为云新鲜技术~
【Java:既然有了synchronized,为什么还要提供Lock?】
推荐阅读
- 附:2种实现方式详细对比 Java 动态代理原理图解
- 深度剖析Java的volatile实现原理,再也不怕面试官问了
- 6 Java多线程:锁与AQS(下)
- 三十九 Java开发学习----SpringBoot整合mybatis
- JavaSPI详解
- day04-JavaScript01
- Java安全之Tomcat6 Filter内存马
- JavaScript的异步编程之Promise
- 5 Java多线程:CAS
- java中HashMap的设计精妙在哪?