Java - 可重入锁(也叫递归锁)
指的是同一个线程 外层 函数获得锁之后,内层 递归函数仍然能够获取该锁的代码,
在同一个线程在 外层方法 获取锁的时候,在进入 内层方法 会自动获取锁
也即是说,线程可以进入任何一个它已经拥有的锁 所同步着的代码块。

synchronized 和 ReentrantLock 是可重入锁的代码证明
注意:
lock.lock(); 与 lock.unlock(); 这里故意写上两次锁并且解两次锁,代码编译没有报错,运行没有报错,程序正常退出
但是如果上锁 和 解锁 不是成对的,代码编译没有问题,程序不能正常退出,因为死锁了。
package com.test.mianshi.lock.可重入锁;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 可重入锁(也叫递归锁)
* 指的是同一个外层函数获得锁之后,内层递归函数仍然能够获取该锁的代码
* 在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁
* <p>
* 也即是说,线程可以进入任何一个它已经拥有锁所同步的代码块
*
* case one 说明 synchronized 是一个典型的 可重入锁
* t1 invoked,sendMsm()
* t1 ##### invoked,sendEmail()
* t2 invoked,sendMsm()
* t2 ##### invoked,sendEmail()
*
* case two 说明 ReentrantLock 是一个典型的 可重入锁
* t3 invoked get()
* t3 ##### invoked set()
* t4 invoked get()
* t4 ##### invoked set()
*/
public class ReenterLockDemo {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
new Thread(() -> {
phone.sendMsm();
}, "t1").start();
new Thread(() -> {
phone.sendMsm();
}, "t2").start();
TimeUnit.SECONDS.sleep(1);
System.out.println();
System.out.println();
Thread t3 = new Thread(phone, "t3");
Thread t4 = new Thread(phone, "t4");
t3.start();
t4.start();
}
}
class Phone implements Runnable{
public synchronized void sendMsm() {
System.out.println(Thread.currentThread().getName() + " invoked,sendMsm()");
sendEmail();
}
public synchronized void sendEmail() {
System.out.println(Thread.currentThread().getName() + " ##### invoked,sendEmail()");
}
Lock lock = new ReentrantLock();
@Override
public void run() {
get();
}
// lock.lock(); 与 lock.unlock(); 这里故意写上两次锁并且解两次锁,代码编译没有报错,运行没有报错,程序正常退出
// 但是如果上锁 和 解锁 不是成对的,代码编译没有问题,程序不能正常退出,因为死锁了。
private void get() {
lock.lock();
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " invoked get()");
set();
}finally {
lock.unlock();
lock.unlock();
}
}
private void set() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " ##### invoked set()");
}finally {
lock.unlock();
}
}
}