为什么需要Lock
synchronized为什么不够用
- 效率低, 释放锁的情况少(代码执行完毕或运行报错, JVM自动释放),获取锁不能设置超时, 不能中断一个试图获取锁的线程.
- 加锁和释放的时机比较单一, 每个锁的条件对象单一(某个对象),Lock则有读写锁
- 无法知道能否获取锁(tryLock, 避免造成死锁)
Lock的常用方法
lock()方法
- lock()方法并不会像synchronized一样自动释放锁, 所以要在finally中手动释放
- lock()方法不能被中断, 一旦陷入死锁就会永久等待
tryLock()方法
- 用来尝试获取锁, 会返回true或者false
- 该方法会立刻返回, 所以可以根据返回值不同来决定接下来的代码走向
tryLock(long time, TimeUnit unit)
- 在一定时间内尝试获取锁, 超时就放弃
- 代码规范
Lock lock = ....;
if(lock.tryLock()) {
try{
....
} finally {
lock.unlock();
}
} else {
......
}
tryLockInterruptiby()
- 相当于把tryLock(long time, TimeUnit unit)的超时时间设为无限,在等待期间可以被中断, 但是抛出interruptedException异常
unlock()
- 解锁
Lock接口的可见性
- happends-before
- 拥有和synchronized同样的内存语义, 下个线程加锁后可以看到上个线程解锁前的所有操作