目录
1、一个synchronized修饰的方法调用另一个synchronized修饰的方法,可以吗?
5、ReentrantLock与Synchronized对比
1、一个synchronized修饰的方法调用另一个synchronized修饰的方法,可以吗?
如果答案是否定的,不能实现这样的调用,那么产生的效果就是,某线程获得了锁并执行方法1的过程中,又要去获得锁以便执行被方法1调用的方法2,方法2 的锁由于已经被执行方法1的线程占用,所以拿不到锁,然后方法1也因此无法继续执行完毕从而线程无法释放锁,于是死锁产生了。
具体看一下效果。
同一个类的两个方法m1和m2都被synchronized关键字修饰,相当于都是对当前对象加锁。
/**
* 一个同步方法可以调用另外一个同步方法,一个线程已经拥有某个对象的锁,再次申请的时候仍然会得到该对象的锁.
* 也就是说synchronized获得的锁是可重入的
*/
package main.java.basic._synchronized;
import java.util.concurrent.TimeUnit;
public class SynCallSyn1 {
synchronized void m1() {
System.out.println("m1 start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
m2();
System.out.println("m1 end");
}
synchronized void m2() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("m2");
}
public static void main(String[] args) {
SynCallSyn1 s=new SynCallSyn1();
new Thread(()->s.m1()).start();
}
}
执行结果:
m1 start
m2
m1 end
综上,synchronized获得锁是可重入的,一个线程获得某个对象的锁,再次申请时仍然会得到该对象的锁。
2、可重入的概念
由此引出了可重入的概念:
可重入就是说某个线程已经获得某个锁,可以再次获取该锁而不会出现死锁。加锁是对同一对象加锁,但是可以加很多次,并且可以释放对应次。