synchronized锁重入验证

文章详细介绍了Java中synchronized锁的重入特性,包括同一线程在本类、子类以及不同类的同步方法间调用的情况,并通过示例代码展示了锁重入的正常运行过程。
摘要由CSDN通过智能技术生成

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修饰方法的写法:

  1. 第一种
synchronized public void method1(){}
  1. 第二种
public synchronized void method1(){}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值