目录
tryLock的同胞兄弟之 tryLock时间控制返回大师 tryLock(long time, TimeUnit unit):
tryLock 和 lock 和 lockInterruptibly 的区别
前言:
我们有一个业务场景,必须生成唯一的自增序列号(作为订单号,订单号的组成是 区县+年月日+后8位序列号,这里的序列号我们使用了 前缀, 例如自增为1的时候 后8位显示为 00000001),
用锁的最佳实践:
- 永远只在更新对象的成员变量时加锁;
- 永远只在访问可变的成员变量时加锁;
- 永远不在调用其他对象的方法时加锁。
tryLock的同胞兄弟之 tryLock时间控制返回大师 tryLock(long time, TimeUnit unit):
tryLock(long time, TimeUnit unit)方法和tryLock()方法是类似的,
只不过区别在于这个方法在拿不到锁时会等待一定的时间,在时间期限之内如果还拿不到锁,就返回false。如果如果一开始拿到锁或者在等待期间内拿到了锁,则返回true。
使用介绍场景:
tryLock 是防止自锁的一个重要方式。
//学习 tryLock
tryLock()方法是有返回值的,返回值是Boolean类型。它表示的是用来尝试获取锁:成功获取则返回true;获取失败则返回false,这个方法无论如何都会立即返回。不会像synchronized一样,一个线程获取锁之后,其他锁只能等待那个线程释放之后才能有获取锁的机会。
一般情况下的tryLock的使用场景:
我这里是用来 控制自增订单号生成使用的, 防止多线程去 请求
Lock lock = new ReentrantLock(); boolean b = lock.tryLock();if(b){ try {//处理任务
}finally { //当获取锁成功时最后一定要记住finally去关闭锁 lock.unlock(); //释放锁 lock.unlock(); } }else { //else时为未获取锁,则无需去关闭锁 //如果不能获取锁,则直接做其他事情 也可以返回为null return null; }第二种 抛出异常写法:
if(b) {
try{
//处理任务
}catch(Exception ex){
}finally{
//当获取锁成功时最后一定要记住finally去关闭锁
lock.unlock(); //释放锁
}
}else {
//else时为未获取锁,则无需去关闭锁
//如果不能获取锁,则直接做其他事情
}
额外技术小知识:
ReentrantLock 与 synchronized
1. ReentrantLock 通过方法 lock()与 unlock()来进行加锁与解锁操作,与 synchronized 会 被 JVM 自动解锁机制不同,ReentrantLock 加锁后需要手动进行解锁。为了避免程序出 现异常而无法正常解锁的情况,使用 ReentrantLock 必须在 finally 控制块中进行解锁操 作。
2. ReentrantLock 相比 synchronized 的优势是可中断、公平锁、多个锁。这种情况下需要 使用 ReentrantLock。
tryLock 和 lock 和 lockInterruptibly 的区别
1. tryLock 能获得锁就返回 true,不能就立即返回 false,tryLock(long timeout,TimeUnit unit),可以增加时间限制,如果超过该时间段还没获得锁,返回 false
2. lock 能获得锁就返回 true,不能的话一直等待获得锁
3. lock 和 lockInterruptibly,如果两个线程分别执行这两个方法,但此时中断这两个线程, lock 不会抛出异常,而 lockInterruptibly 会抛出异常。