如何证明synchronized内建锁的可重入性和互斥性

在证明synchronized内建锁的可重入性和互斥性之前,我们需要了解一下synchronized如何实现线程同步问题,详情可参见https://blog.csdn.net/ty6693/article/details/89307414这篇文章。

一、证明锁的可重入性

锁的可重入性:同一个线程再次获得锁时可以获取成功而其他线程获取锁会阻塞(同一个线程重复获取同一把锁)

分析:

要证明锁的可重入性,就要验证当一个线程取得某个对象的对象锁(对象的监视器monitor)之后,即此时执行了该对象的一个同步方法,此时如果此同步方法中包含了该对象的另外一个同步方法,该线程是否可以继续执行,如果可以执行的话,证明该线程可以再次获取该对象锁,即证明了锁的可重入性。

class MyThreadX implements Runnable {
    @Override
    public void run() {
        test1();
    }

    private synchronized void test2() {
        System.out.println(Thread.currentThread().getName() + "进入test2方法");
    }

    private synchronized void test1() {
        if (Thread.currentThread().getName().equals("A")){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("A进入test1方法");
            test2();
        }
    }
}

public class Test12 {
    public static void main(String[] args) {
        MyThreadX mt = new MyThreadX();
        Thread thread = new Thread(mt, "A");
        thread.start();
    }
}

执行结果:

上述结果表明,当线程在执行一个对象的某一个同步方法时,如果这个同步方法中还调用了该对象的其它同步方法,则该线程可以继续执行这个同步方法,即证明了锁的可重入性。

二、证明锁的互斥性

分析:要证明锁的互斥,我们可以启动两个线程分别访问某对象的两个同步方法,为了可以更好的观察结果,我们可以给其中一个同步方法中写一个死循环。此时如果两个对象分别能进入到该对象的两个同步方法,说明锁不是互斥的;反之说明锁是互斥的。

class MyThreadX implements Runnable{
    @Override
    public void run() {
        test1();
        test2();
    }
    private synchronized void test2() {
        if(Thread.currentThread().getName().equals("B")){
            System.out.println("B进入test2方法");
        }
    }
    private synchronized void test1() {
        if(Thread.currentThread().getName().equals("A")){
           while (true){}
        }
    }
}

public class Test12 {
    public static void main(String[] args) {
        MyThreadX mt=new MyThreadX();
        Thread thread=new Thread(mt,"A");
        Thread thread1=new Thread(mt,"B");
        thread.start();
        thread1.start();
    }
}

执行结果:

观察打印结果我们可以发现,由于A线程执行的该对象的test1方法中是一个无任何内容的空结构体,此时结果中也没有任何内容,说明B线程并没有执行该对象的test2方法【如果执行了的话会打印东西】,则说明B线程并没有获取到该对象的对象锁,即证明了锁的互斥性。

此时要是调试程序,我们可以看到如下结果:

通过调试我们可以看到此时A线程的状态时执行状态,而B线程由于执行monitorenter时发现monitor计数器不为0,所以正处于获取对象锁的状态,也证明了锁的互斥性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值