lock的 简介 地位 作用
- 锁是一种工具,用于控制对
共享资源
的访问 - Lock和synchronized是最常见的两个锁,他们都能够达到线程安全的目录,但是使用和功能上又有较大的不同
- Lock接口最常见的实现类就是
ReentrantLock
- 通常情况下Lock只允许一个线程访问共享资源,特殊情况也允许多个线程并发访问,如ReadWriteLock的ReadLock
为什么需要Lock?
效率低
:锁的释放情况少(只有执行结束或者抛异常才能释放锁)、试图获取锁时不能设定超时、不能中断一个正在试图获取锁的线程不够灵活
:加锁和释放的时机单一(不像读写锁那样针对不同场景而选择使用读锁或写锁),每个锁仅有单一的条件(某个对象),适用场景可能是不够的- 无法知道是否
成功获取到锁
Lock接口拥有而synchronized关键字不具备的主要特性:
特性 | 描述 |
---|---|
尝试非阻塞地获取锁:tryLock() | 当前线程尝试获取锁,如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁,否则立即返回false |
能被中断地获取锁:lockInterruptibly() | 在等待获取锁的线程能够响应中断,等待锁的线程被中断时,中断异常将会被抛出,不再等待 |
超时获取锁:tryLock(long time, TimeUnit unit) | 在指定的截止时间之前获取锁, 超过截止时间后仍旧无法获取则返回 |
Lock接口基本的方法:
方法名称 | 描述 |
---|---|
void lock() | 获得锁。如果锁已经被其他线程获取,则进行等待 |
boolean tryLock() | 只有在调用时才可以获得锁。如果可用,则获取锁定,并立即返回值为true;如果锁不可用,则此方法将立即返回值为false 。 |
boolean tryLock(long time, TimeUnit unit) | 超时获取锁,当前线程在一下三种情况下会返回: 1. 当前线程在超时时间内获得了锁;2.当前线程在超时时间内被中断;3.超时时间结束,返回false. |
void lockInterruptibly() | 获取锁,如果可用并立即返回。如果锁不可用,那么等待,和 tryLock(long time, TimeUnit unit) 方法不同的是等待时间无限长,但是在等待中可以中断当前线程(响应中断)。 |
Condition newCondition() | 获取等待通知组件,该组件和当前的锁绑定,当前线程只有获得了锁,才能调用该组件的wait()方法,而调用后,当前线程将释放锁。 |
void unlock() | 释放锁。 |
- Lock不会像synchronized一样在异常时自动释放锁,使用时,一定要在finally中释放锁
- lock()方法 不能被中断,一旦死锁,lock() 就会永久等待