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();
}
}
}