述
在并发开发中,锁也是经常使用的一个工具,主要是用于对并发资源的访问,常用的锁就是 Lock
和 synchronized
,这两个锁都可以达到线程安全的目的,但是在使用上有较大差别.
Lock 和 synchronized
Lock
一般情况用于 synchronized
不满足要求或者不合适的时候, Lock
是一个接口,最常用的实现类就是 ReentrantLock
,一般情况下 Lock
只允许一个线程访问共享资源,但是也有特殊的锁可以实现并发访问,比如读写锁(ReadWriteLock
)中的读锁(ReadLock
)
synchronized 的劣势
既然有了 synchronized
为什么还需要 Lock
?
相比于 Lock
, synchronized
有以下几个不足之处:
- 效率低,锁的释放情况少,试图获得锁时不能设定超时时间,而且不能中断一个正在获得锁的线程
- 不够灵活,加锁和释放的时机单一,每个锁仅有单一的条件(某个对象)在一些情况下时不够的
- 无法知道是否成功获取锁
Lock 的基本使用
常用方法
Lock
中有以下4个获取锁的方法
lock()
: 阻塞去获取锁,直到获取成功(所以一旦出现死锁的情况线程将永久阻塞),跟synchronized
相比,lock
不会再异常中释放锁,所以一定要在finally
中释放锁tryLock()
: 尝试获取锁,不会阻塞,立即返回有没有成功获取到,获取到的话返回 true ,否则返回 falsetryLock(long time, TimeUnit unit)
: 加一个等待时间,在等待时间内尝试获取锁,超时就放弃,获取到的话返回 true ,否则返回 falselockInterruptibly()
: 这个方法相当于把tryLock(long time, TimeUnit unit)
中的时间设置为无限,但是这个方法获取锁的过程中,线程可以中断
释放锁的方法为 unlock()
synchronized
和 Lock
都可以保证可见性,就是说,当前线程获取到锁之后,可以看到上一个线程做的所有操作
总结
对锁做一个简单的介绍,以及 Lock
的基本使用