相比于synchronized具备以下特点
- 可中断(防止死锁避免无限制的等待)
- 可以设置超时时间(超时后可放弃对锁的争夺)
- 可以设置为公平锁(FIFO可以避免饥饿问题)
- 支持多个条件变量(支持多个waitset,不满足哪个条件到哪个waitset去等)
- 与synchronized一样,都支持可重入,但是需要手动加锁和释放
ReentrantLock lock = new RentrantLock();
//获取锁(不可打断的加锁方式)
lock.lock();
//获取锁(可打断的加锁方式)
lock.lockInterruptibly();
//获取锁(尝试获得锁,可以设置超时时间,会返回boolean值)
lock.trylock();
try{
//临界区
} finally{
//释放锁
lock.unlock();
}
try{
if(!lock.tryLock(1,TimeUnit.SECONDS)){
return;
}
} catch(InterruptedException e){
//获取不到锁
e.printStackTrace();
return;
}
锁超时-解决哲学家就餐问题
//哲学家问题
synchronized(left){
synchronized(right){
eat();
}
}
if(left.tryLock()){
try{
if(right.tryLock()){
try{
eat();
} finally{
right.unlock();
}
}
} finally{
left.unlock();
}
}
公平锁
reentrantLock默认时不公平的,但公平锁一般没有必要,会降低并发度。
ReentrantLock lock = new RentrantLock(true);
条件变量
ReentrantLock lock = new Reentrantlock();
//创建一个新的条件变量
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
lock.lock();
//进入对应条件变量等待
condition1.await();
//唤醒方法
condition1.signal();
condition1.signalAll();