首先让我们关注下面几个问题:
为什么需要锁?
- 多任务环境对同一共享资源进行读写操作
- 对资源的访问是互斥的
锁的生命周期?
- 竞争锁
- 占有锁
- 任务阻塞
- 释放锁
什么是Lock锁?
- Lock是一个类,通过这个类可以实现同步访问
- Lock是JDK5后才出现的类
- Lock在JUC包下有很多实现类,主要的实现类是ReentrantLock(可重入锁)
- Lock给我们提供了5个重要的方法:unlock(释放锁)、lock(加锁)、tryLock(获取空闲状态下的锁,可以响应中断)、newCondition(获取绑定此 Lock 实例的Condition 实例,用于控制多线程之间的、基于该状态的条件等待)、lockInterruptibly(如果当前线程未被中断,则获取锁,可以响应中断)
Lock获取锁的几种方式:
Lock lock = new ReentrantLock();
lock.lock();
try {
//处理事务
}catch (Exception e){
e.printStackTrace();
}finally {
//释放锁
lock.unlock();
}
Lock lock = new ReentrantLock();
if (lock.tryLock()) {
try {
//处理事务
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
lock.lockInterruptibly();
try {
//处理事务
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
}
}
什么是ReentrantLock?
ReentrantLock是基于AQS实现的
ReentrantLock根据传入构造方法的布尔型参数实例化出Sync的实现类FairSync和NonfairSync,分别表示公平的Sync和非公平的Sync
Lock和Synchronized的区别?
- Lock可使用的场景更多,更灵活
- Synchronized是隐式锁,Lock是显示锁,即Lock需要手动释放锁,如果不释放锁可能会出现死锁(如果没有解锁,在程序正常运行中,线程正常退出后也会释放锁),而Synchronized不需要
- Synchronized是不可中断的,除非抛出异常或者正常运行完成,而Lock可以中断的。中断方式:①调用设置超时方法tryLock(long timeout ,timeUnit unit) ②调用lockInterruptibly()放到代码块中,然后调用interrupt()方法可以中断
- Synchronized:非公平锁,Lock:可设置非公平锁与公平锁,在其构造方法的时候可以传入boolean值(true:公平锁,false:非公平锁),默认是非公平锁
网友评论