文章目录
synchronized锁重入验证
1. 可重入锁
可重入锁:也叫递归锁,指的是同一线程的外层函数获得锁之后,内层递归函数仍然能获取该锁的代码。
即同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。线程可以进入任何一个它已经拥有的锁所同步着的代码块。
2. synchronized锁重入
synchronized是支持锁重入的,是可重入锁。
- 同一线程在本类同步方法内部可以调用本类其它同步方法
- 同一线程子类同步方法内部可以调用父类的同步方法
- 同一线程在A类的同步方法内部可以调用B类的同步方法
2.1 本类同步方法内部调用本类其它同步方法
同一线程在本类同步方法内部可以调用本类其它同步方法
SyncObjMthod类:
public class SyncObjMthod {
synchronized public void method1(){
System.out.println("线程 "+Thread.currentThread().getName()+"\t调用 method1...");
method2();
}
synchronized public void method2(){
System.out.println("线程 "+Thread.currentThread().getName()+"\t调用 method2...");
method3();
}
synchronized public void method3(){
System.out.println("线程 "+Thread.currentThread().getName()+"\t调用 method3...");
}
}
TestSyncRenntry测试类:
public class TestSyncRenntry {
public static void main(String[] args) {
new Thread(() -> {
SyncObjMthod syncObjMthod = new SyncObjMthod();
syncObjMthod.method1();
}, "AAA").start();;
}
}
输出结果:
线程 AAA 调用 method1...
线程 AAA 调用 method2...
线程 AAA 调用 method3...
2.2 子类同步方法内部调用父类的同步方法
同一线程子类同步方法内部可以调用父类的同步方法
父类Father:
public class Father {
public int i =10;
public synchronized void fatherMethod(){
try {
i--;
System.out.println("线程 "+Thread.currentThread().getName()+"\t调用 fatherMethod i="+i);
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
子类Sub:
public class Sub extends Father {
public synchronized void subMethod() {
try {
while (i > 0) {
i--;
System.out.println("线程 "+Thread.currentThread().getName()+"\t调用 subMethod i=" + i);
TimeUnit.SECONDS.sleep(5);
this.fatherMethod();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
测试类TestSyncRenntry1:
public class TestSyncRenntry1 {
public static void main(String[] args) {
new Thread(()->{
Sub sub = new Sub();
sub.subMethod();
},"BBB").start();
}
}
输出结果:
线程 BBB 调用 subMethod i=9
线程 BBB 调用 fatherMethod i=8
线程 BBB 调用 subMethod i=7
线程 BBB 调用 fatherMethod i=6
线程 BBB 调用 subMethod i=5
线程 BBB 调用 fatherMethod i=4
线程 BBB 调用 subMethod i=3
线程 BBB 调用 fatherMethod i=2
线程 BBB 调用 subMethod i=1
线程 BBB 调用 fatherMethod i=0
2.3 A类的同步方法内部调用B类的同步方法
同一线程在A类的同步方法内部可以调用B类的同步方法
public class A {
B b = new B();
public synchronized void method(){
System.out.println("线程 "+Thread.currentThread().getName()+"\t调用 A类 method方法");
b.method();
}
}
public class B {
public synchronized void method(){
System.out.println("线程 "+Thread.currentThread().getName()+"\t调用 B类 method方法");
}
}
public class TestDemo1 {
public static void main(String[] args) {
new Thread(()->{
A a = new A();
a.method();
},"CCC").start();
}
}
线程 CCC 调用 A类 method方法
线程 CCC 调用 B类 method方法
3. synchronized修饰方法写法
synchronized修饰方法的写法:
- 第一种
synchronized public void method1(){}
- 第二种
public synchronized void method1(){}