java基础(jdk1.8)
**
多线程—ReentrantLock使用
**
此篇博客主要讲如何使用ReentrantLock
本篇链接
文章目录
- 多线程—ReentrantLock使用
- ReentrantLock的简介
- 方法
- 公平锁
- 与synchronized比较
ReentrantLock的简介
ReentrantLock是Java的一个类
底层使用CAS
ReentrantLock锁可以代替synchronized,而且控制更加方便
但线程数小于等于2的时候(简单模型)使用synchronized
方法
- lock();
加锁,但必须必须必须手动释放锁
syn锁定如果遇到异常的时候,jvm会自动释放锁,但lock必须手动释放锁,因此常在finally内进行锁的释放unlock();
- tryLock();
尝试加锁,不管锁定与否,方法都继续执行
boolean类型返回值,true表示拿到锁,false表示没有拿到锁
tryLock(时间长度,时间单位);等待给定时间长度,如果还拿不到锁,继续执行
- lockInterruptibly();
同lock,可加锁,但可以对interrupt()方法做出响应
也就是其他线程调用当前用此方法等待线程的interrupt方法可以打断阻塞状态
ReentrantLock o1 = new ReentrantLock();
//普通加锁
public void method1(){
o1.lock();
System.out.println("method1 加锁区间");
o1.unlock();
}
//尝试加锁
public void method2(){
o1.tryLock();
System.out.println("method2 加锁区间");
o1.unlock();
}
//尝试加锁 (1s拿不到锁继续执行)
public void method3(){
boolean flag = false;
try {
flag = o1.tryLock(1,TimeUnit.SECONDS);
if (flag == true)
{
System.out.println("method3 加锁区间");
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
if (flag == true) o1.unlock();
}
}
//相应打断式加锁
public void method4(){
try {
o1.lockInterruptibly();
System.out.println("method4 加锁区间");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
o1.unlock();
}
}
公平锁
reentrantLock可以指定为公平锁
ReentrantLock rl = new ReentrantLock(true);
synchronized是非公平锁。等待某资源的所有线程都是等概率拿到锁
公平锁则是对等待线程的等待时间进行计时,保证公平,谁等待时间长谁拿锁
公平锁效率较非公平差
ReentrantLock详解
与synchronized比较
- 使用
synchronized是Java关键字,而ReentrantLock是类
- 加锁方式
synchronized加的是对象锁,是锁膨胀的一个过程,锁膨胀不可逆
ReentrantLock是通过方法加锁,底层是CAS+AQS
- 公平锁
ReentrantLock可以指定公平锁,默认非公平。
synchronized是非公平锁
- 响应
ReentrantLock可以尝试加锁,获不获得锁都会继续执行,且可以指定等待获取锁的时间。还可以指定对Interrupter做出相应
synchronized必须拿到锁才能执行,而且synchronized无法指定锁的获取时间
- 释放
ReentrantLock必须手动释放锁
synchronized会自动释放锁