可重入锁顾名思义可以重复利用的锁,但不是任何方法都能重复使用,而是最初占有锁的方法调用的方法,即是调用方法与被调方法可以同时占用同一把锁。
下面从三个角度来说明:
1.被调方法没有加锁
public class LockTest {
private static final Object obj=new Object();
public void method1(){
synchronized (obj){
System.out.println("method1执行了");
method2();
System.out.println("回到了method1");
}
}
public void method2(){
System.out.println("method2执行了");
}
public static void main(String[] args) {
LockTest lockTest=new LockTest();
lockTest.method1();
}
}
这种情况只有method1占用了锁,在调用method2,method1等待method2执行完即可再次执行释放锁
执行结果:
method1执行了
method2执行了
回到了method1
2.被调方法需要同样的锁,该锁为可重入锁
public class LockTest {
private static final Object obj=new Object();
public void method1(){
synchronized (obj){
System.out.println("method1执行了");
method2();
System.out.println("回到了method1");
}
}
public void method2(){
synchronized (obj) {
System.out.println("method2执行了");
}
}
public static void main(String[] args) {
LockTest lockTest=new LockTest();
lockTest.method1();
}
}
这种情况method1先占用了锁,之后调用method2,发现method2也需要相同的锁,因为method2是method1的调用方法和synchronized是可重入锁(Reentrantlock也是)这两个条件,method2也占用了这把锁,即是method1,method2占用了同一把锁。
执行结果:
method1执行了
method2执行了
回到了method1
3.被调方法需要同样的锁,该锁是不可重入锁
因为jdk自带的锁都是可重入锁,采用在method2的synchronized锁前添加wait的方式模拟不可重入锁
public class LockTest {
private static final Object obj=new Object();
public void method1() throws InterruptedException {
synchronized (obj){
System.out.println("method1执行了");
method2();
System.out.println("回到了method1");
}
}
public void method2() throws InterruptedException {
wait();
synchronized (obj) {
System.out.println("method2执行了");
}
}
public static void main(String[] args) throws InterruptedException {
LockTest lockTest=new LockTest();
lockTest.method1();
}
}
这种情况也是method1先占用了锁,之后调用method2,发现method2也需要相同的锁,但不同的是:此时的锁是不可重入锁(模拟的)。method2因为拿不到锁不能继续执行,需要method1释放锁,而method1也在等待method2执行完后进行下一步操作,这样就相互等待产生死锁。
执行结果:
method1执行了
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:328)
at com.heimaweb.day1.LockTest.method2(LockTest.java:18)
at com.heimaweb.day1.LockTest.method1(LockTest.java:13)
at com.heimaweb.day1.LockTest.main(LockTest.java:26)
method2并没有输出
总结:可重入锁是调用方法与被调方法可以同时调用的一种锁,它的作用是防止调用方法与被调方法方法相互等待产生死锁现象。(因为jdk中自带的锁基本上都是可重入锁,所以可以放心用)
标签:重入,method2,method1,LockTest,含义,Object,解决,public From: https://www.cnblogs.com/swliujavajourney/p/17991463