一. 可重入锁(递归锁)
1. 定义:
指的时同一线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,
在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁,也就是说,
线程可以进入任何一个它已经拥有的锁所同步着的代码块。
简单来说,可重入锁就是你回家后开了一个大门锁,就可以进入厨房,厕所,客厅等等。
2. 可重入锁作用:最大的作用就是避免死锁
3. 使用synchronized实现可重入锁
class Phone {
//证明 synchronized实现可重入锁
public synchronized void sendSMS() throws Exception {
System.out.println(Thread.currentThread().getName()+ "\t invoked sendMS()");
sendEmail();
}
public synchronized void sendEmail() throws Exception {
System.out.println(Thread.currentThread().getName() + "\t ### invoked sendEmail()");
}
}
调用
public static void main(String[] args) throws Exception{
System.out.println("验证 synchronized 可重入锁。。。");
Phone phone = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "t1").start();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "t2").start();
运行结果:
4. 使用ReentrantLock实现可重入锁
class Phone implements Runnable{
//证明 ReentrantLock实现可重入锁
Lock lock = new ReentrantLock();
@Override
public void run() {
get();
}
public void get() {
//加锁几次就要解锁几次,要不然就会卡死,出不去。
lock.lock();
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+ "\t invoked get()");
set();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
lock.unlock();
}
}
public void set() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+ "\t invoked set()");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
调用
public static void main(String[] args) throws Exception{
System.out.println("验证 ReentrantLock 可重入锁。。。");
Phone phone = new Phone();
Thread t3 = new Thread(phone, "t3");
Thread t4 = new Thread(phone, "t4");
t3.start();
t4.start();
}
运行结果:
总结:使用synchronized和ReentrantLock都可以实现可重入锁。
标签:重入,面试题,Java,Thread,lock,void,Exception,new
来源: https://blog.csdn.net/w_x_A__l__l/article/details/106870216