多线程基础学习十:java.util.lock.concurrent.locks中lock

java.util.lock.concurrent.locks是1.5之后出现的一个多线程包,里面提供了同步的另外一种实现方式,前面学习了Synchronized和volatile的基本用法,现在学习一下这些这些接口和类。

java.util.lock.concurrent.locks里面有三个顶级接口:
Lock
Condition
ReadWriteLock

Lock

前面学习的时候知道,并发包含了原子性、一致性,synchronized实现了这些特征,在实现这些特征的时候,有获取锁和释放锁的功能,而lock则是实现了获取锁和释放锁的接口。

这个接口有六个方法:
void lock()
void lockInterruptibly()
boolean tryLock()
boolean tryLock(long time, TimeUnit unit)
unlock()
newCondition()

lock

调用这个方法,尝试获取锁,如果获取不到,线程就会不可用,我的理解是会进入等待状态。

lockInterruptibly

调用这个方法,尝试获取锁,如果获取不到,线程就会不可用,在获取锁期间,如果遇到了中断,就会抛出InterruptedException,所以可想而知,用这个方法是需要捕获InterruptedException的。

boolean tryLock()

调用这个方法,尝试获取锁,如果获取到,返回true,否则返回false;结果立刻返回,不会持续获取。

boolean tryLock(long time, TimeUnit unit)

调用这个方法,尝试获取锁,持续获取指定的时间,如果获取到,返回true,否则返回false或者抛出InterruptedException异常。

unlock()

释放锁。

在了解上面方法的基础上,可以知道,有获取锁,就需要释放锁;如果发生了某种错误,导致锁没有释放掉,其它线程无法获取锁,此时就会出现死锁现象。

所以,unlock方法一般都写在finally方法里面。

基本用法

获取锁的方法是否可以写在try块中?

伪代码:
写在外面

lock.lock();
try {

} finally {
    lock.unlock();
}

写在里面

try {
 lock.lock();
} finally {
    lock.unlock();
}

以前看过别人写的代码,很多人都会说,不要把获取锁放在try块中,但是为什么呢?

lock()方法的注释里,有这么一句话:

A Lock implementation may be able to detect erroneous use of the lock, such as an invocation that would cause deadlock, and may throw an (unchecked) exception in such circumstances. The circumstances and the exception type must be documented by that Lock implementation

简而言之,在获取锁期间,可能会抛出unchecked Exception。

如果lock()在try块之外,当获取锁失败之后,是不会执行unlock()方法的。
如果lock()在try块之内,当获取锁失败之后,会执行unlock()方法,然后会执行失败(未获取锁,却释放锁),抛出IllegalMonitorStateException异常(后面用代码验证)。

所以,一般获取锁,都要放在try块之外,释放锁在finally中;未获取锁,就不要释放锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值