参考黑马程序猿 并发教程
https://www.bilibili.com/video/BV16J411h7Rd?p=120
特点
- 可中段
- 可以设置超时时间
- 可以设置为公平锁
- 支持多个条件变量
与sychronized一样,都支持可重入
基本用法
关注:lock必须与unlock成对出现,unlock必须放在finally的最后,lock后紧跟try在try外部和里面是一样的
//锁是静态不可变对象,保证了只有一个锁
private static final ReentrantLock reentrantLock = new ReentrantLock();
public static void main(String[] args) {
//上锁和解锁是成对的,解锁必须放在finally的最后
reentrantLock.lock();
try {
System.out.println("hello");
throw new IOException("can find file");
} catch (IOException e) {
System.out.println("service not avaliable");
} finally {
reentrantLock.unlock();
}
}
可重入
https://blog.csdn.net/u012545728/article/details/80843595
可重入:同一个线程如果首次获得了锁,再次获得锁时是可以直接进入的
不可重入:同一个线程如果首次获得了锁,再次获得锁时是会阻塞的
实例,m1是重新加锁,output如下,可以看到确实是重新进入了。
hello
m1 lock
service not avaliable
//锁是静态不可变对象,保证了只有一个锁
private static final ReentrantLock reentrantLock = new ReentrantLock();
public static void main(String[] args) {
//上锁和解锁是成对的,解锁必须放在finally的最后
reentrantLock.lock();
try {
System.out.println("hello");
m1();
throw new IOException("can find file");
} catch (IOException e) {
System.out.println("service not avaliable");
} finally {
reentrantLock.unlock();
}
}
public static void m1() {
reentrantLock.lock();
try {
System.out.println("m1 lock");
throw new IOException();
} catch (IOException e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}
可打断
输出如下:
打断Thread1的等待
t1 is interrupted
thread is interptued
可以看到打断后返回了,然后执行了后面的,如果打断后不返回,就会继续执行下面的 thread get lock,
//锁是静态不可变对象,保证了只有一个锁
private static final ReentrantLock reentrantLock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
reentrantLock.lock();
Thread t1 = new Thread(()->{
try {
//如果有晶振
reentrantLock.lockInterruptibly();
}catch (InterruptedException e) {
System.out.println("thread is interptued");
return;
}
try{
System.out.println("thread1 get lock");
throw new IOException();
}catch (IOException e){
}
finally {
reentrantLock.unlock();
}
},"thread1");
t1.start();
System.out.println("打断Thread1的等待");
Thread.sleep(5);
t1.interrupt();
System.out.println("t1 is interrupted");
}
设置等待时间
private static final ReentrantLock reentrantLock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
reentrantLock.lock();
Thread t1 = new Thread(() -> {
try {
//此处可以带参数,也可以不带参数,返回时一个boolean
if (!reentrantLock.tryLock(5, TimeUnit.SECONDS)) {
System.out.println("thread1 not get lcck");
return;
}
} catch (InterruptedException e) {
System.out.println("thread1 not get lcck");
e.printStackTrace();
}
try {
System.out.println("thread get lock");
} finally {
reentrantLock.unlock();
}
}, "thread1");
t1.start();
Thread.sleep(2);
System.out.println("main after 1s unlock");
reentrantLock.unlock();
}
公平锁
ReentrantLock默认是不公平锁,构造函数设置成true时,会是公平锁
private static final ReentrantLock reentrantLock = new ReentrantLock(true);