可重入锁
1.概述
-
可重入锁又名递归锁。
-
它是指一个线程在外层获取锁之后,再进入该线程内部的方法时就会自动获得这把锁,不会因为之前获取了这把锁后没有释放而阻塞。
-
Java中的synchronized和ReentrantLock都是可重入锁。
-
可重入锁的优点在于可以在一定程度上避免死锁。
2.分类
2.1 隐式锁
即synchronized同步锁(默认是可重入锁)
在一个由synchronized关键字修饰的方法或代码块的内部调用本类的其他synchronized修饰的方法或代码块时,是永远可以得到锁的
-
同步代码块
package com.example.juctest.reEnterLock; /** * @author Sonnie Guo * @PackageName:com.example.juctest.reEnterLock * @ClassName:ReenterLockDemo * @Description:ReEnterLockDemo */ @SuppressWarnings({"all"}) public class ReenterLockDemo { public static final String ReenterLock = "lock"; public static void main(String[] args) { reenterLock_codeBlock_demo(); } public static void reenterLock_codeBlock_demo(){ new Thread(()->{ synchronized (ReenterLock.intern()){ System.out.println(Thread.currentThread().getName()+"\t外部调用"); synchronized (ReenterLock.intern()){ System.out.println(Thread.currentThread().getName()+"\t中部调用"); synchronized (ReenterLock.intern()){ System.out.println(Thread.currentThread().getName()+"\t内部调用"); } } } },"AAA").start(); } }
-
同步方法
package com.example.juctest.reEnterLock; /** * @author Sonnie Guo * @PackageName:com.example.juctest.reEnterLock * @ClassName:ReenterLokckDemo2 * @Description:ReEnterLokckDemo2 */ @SuppressWarnings({"all"}) public class ReenterLokckDemo2 { public static void main(String[] args) { reenterLock_func1(); } public synchronized static void reenterLock_func1(){ System.out.println("-----out-----"); reenterLock_func2(); } public synchronized static void reenterLock_func2(){ System.out.println("-----middle-----"); reenterLock_func3(); } public synchronized static void reenterLock_func3(){ System.out.println("-----inner-----"); } }
2.2 显式锁
即Lock。
注意:加了几次锁,就必须解几次锁。
举个例子,如果加了2次锁,少解了一次,那么下一个线程将始终无法获得锁,导致一直运行不下去;
如果多解了一次,程序会运行,但会抛出java.lang.IllegalMonitorStateException;
package com.example.juctest.reEnterLock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Sonnie Guo
* @PackageName:com.example.juctest.reEnterLock
* @ClassName:ReEnterLockDemo3
* @Description:ReenterLockDemo3
*/
@SuppressWarnings({"all"})
public class ReenterLockDemo3 {
static Lock reentrantLock = new ReentrantLock();
public static void main(String[] args) {
reenterLock_LockDemo();
}
public synchronized static void reenterLock_LockDemo(){
new Thread(()->{
reentrantLock.lock();
try {
System.out.println("------out-----");
reentrantLock.lock();
try {
System.out.println("------in-----");
} catch (Exception e) {
e.printStackTrace();
}finally {
reentrantLock.unlock();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
reentrantLock.unlock();
}
},"AAA").start();
}
}