两者比较:
特性 | Synchronized | Lock |
---|---|---|
内置、关键字 | 是 | 否 |
需手动释放锁 | 不必 | 必须 |
重入性 | 支持 | 支持 |
中断锁 | 不支持 | 支持 |
公平锁 | 不支持 | 支持 |
读写锁 | 不支持 | 支持 |
相关概念解析
-
可重入锁
如果锁具备可重入性,则称作为可重入锁。
假设方法A需要获取锁,方法B也需要获取锁,如果执行方法A会调用方法B,则直接执行,不需要重新获取锁,否则就会一直等待下去。 -
可中断锁
就是支持手动终端锁
lock可通过lockInterruptibly支持中断锁
synchronized只有一下两种情况才会释放锁: -
获取锁的线程执行完了该代码块
-
线程执行发生异常,JVM会让线程自动释放锁
-
公平锁
即尽量以请求锁的顺序来获取锁。
lock创建的时候支持设置公平锁,默认是非公平锁。
synchronized就是非公平锁,执行顺序是随机的。 -
读写锁
lock的ReentrantReadWriteLock可以通过readLock()获取读锁,通过writeLock()获取写锁。只有不同操作的锁之间是互斥的。
synchronized 不区分,完全锁
lock的简单使用
- 定义
public interface Lock {
void lock();//获取锁
void lockInterruptibly() throws InterruptedException;//获取中断锁
boolean tryLock();//尝试获取锁
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();//释放锁
Condition newCondition();//新建一个锁环境
}
- 基本使用
Lock lock = ...;//定义锁
lock.lock();//获取锁
try{
//处理任务
}catch(Exception ex){
//捕获异常
}finally{
lock.unlock(); //释放锁
}
- 中断锁
使用中断锁lockInterruptibly必须能抛出异常,千万别在方法内自行捕获了。
通常调用interrupt()方法是不能中断正在运行过程中的线程,只能中断阻塞过程中的线程。
所以方法同过lockInterruptibly在等待获取锁的时候,是可以响应中断的,而synchronized只能一直等待下去。
public void method() throws InterruptedException {
lock.lockInterruptibly();
try {
//.....
}
finally {
lock.unlock();
}
}
- 尝试获取锁
Lock lock = ...;
if(lock.tryLock()) {
try{
//处理任务
}catch(Exception ex){
}finally{
lock.unlock(); //释放锁
}
}else {
//如果不能获取锁,则直接做其他事情
}
网友评论