ReentrantLock特点
相对于 synchronized 它具备如下特点
可中断
可以设置超时时间
可以设置为公平锁
支持多个条件变量
与 synchronized 一样,都支持可重入
基本使用语法如下:
public class Test {
public static void main(String[] args) {
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();
try{
// 业务代码逻辑
}finally {
reentrantLock.unlock();
}
}
}
可重入
可重入是指同一个线程如果首次获得了这把锁,那么因为它是这把锁的拥有者,因此有权利再次获取这把锁。如果是不可重入锁,那么第二次获得锁时,自己也会被锁挡住
import java.util.concurrent.locks.ReentrantLock;
public class Test {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
m1();
}
public static void m1(){
lock.lock();
try{
System.out.println("m1 加锁成功");
m2();
}finally {
lock.unlock();
}
}
public static void m2(){
lock.lock();
try{
System.out.println("m2 加锁成功");
m3();
}finally {
lock.unlock();
}
}
public static void m3(){
lock.lock();
try{
System.out.println("m2 加锁成功");
}finally {
lock.unlock();
}
}
}
运行结果:可以发现全部加锁成功了
可打断
调用lockInterruptibly()方法执行打断
import java.util.concurrent.locks.ReentrantLock;
import static java.lang.Thread.sleep;
public class Test {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Thread t1 = new Thread(() -> {
System.out.println("线程1开始执行");
try {
lock.lockInterruptibly();
} catch (Exception e) {
System.out.println("线程1锁被打断");
e.printStackTrace();
return;
}
try {
System.out.println("线程1加锁成功");
} finally {
lock.unlock();
}
}, "t1");
lock.lock();
System.out.println("主线程获得了锁");
t1.start();
try{
sleep(1);
t1.interrupt();
System.out.println("执行打断");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
注意如果是不可中断模式,那么即使使用了 interrupt 也不会让等待中断
例子:
import java.util.concurrent.locks.ReentrantLock;
import static java.lang.Thread.sleep;
public class Test {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Thread t1 = new Thread(() -> {
System.out.println("线程1开始执行");
try {
lock.lock();
} catch (Exception e) {
System.out.println("线程1锁被打断");
e.printStackTrace();
return;
}
try {
System.out.println("线程1加锁成功");
} finally {
lock.unlock();
}
}, "t1");
lock.lock();
System.out.println("主线程获得了锁");
t1.start();
try{
sleep(1);
t1.interrupt();
System.out.println("执行打断");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
执行结果: