美文网首页
可重入锁

可重入锁

作者: 装完逼立马跑 | 来源:发表于2018-07-17 16:51 被阅读0次

    java多线程编程核心技术2.1.6章-锁重入



    在看到这里时,一直理解不来父类子类的可重入锁,一直纠结,如果在父类的对象锁被a线程一直持有时,b线程在持有子类的对象锁时,b线程怎么通过super调用父类同步方法的,于是手写测试了一下

    public class Super {
    
        synchronized public void method1() throws InterruptedException {
            System.out.println("super method1 :"+Thread.currentThread().getName());
            for (int i = 0; i < 100000; i++) {
                System.out.println("super method1 :"+i);
                Thread.sleep(500);
            }
        }
    
        synchronized public void method2() throws InterruptedException {
            System.out.println("super method2 :"+Thread.currentThread().getName());
            for (int i = 0; i < 5; i++) {
                System.out.println("super method2 begin");
                Thread.sleep(1000);
            }
            System.out.println("super method2 end");
        }
    }
    
    public class Child extends Super {
        synchronized public void method3() throws InterruptedException {
            System.out.println("child method3 begin");
            super.method2();
            System.out.println("child method3 end");
        }
    
        public void method5(){
            System.out.println("child method5");
            super.method4();
            System.out.println("end");
        }
    }
    
    public class SuperThread extends Thread {
        @Override
        public void run() {
            try {
                Super s = new Super();
                s.method1();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public class ChildThread extends Thread {
        @Override
        public void run() {
            try {
                Child c = new Child();
                c.method3();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public class TestMain {
        public static void main(String[] args) throws InterruptedException {
            SuperThread superThread = new SuperThread();
            ChildThread childThread = new ChildThread();
            //启动线程跑父类同步方法a,无限循环输出
            superThread.start();
    
            Thread.sleep(10000);
            //再跑子类同步方法,该同步方法会调用父类的另一个同步方法
            childThread.start();
        }
    }
    

    得出的结论是,两个线程时并行走的,所以说,childThread线程只是取到了child的对象锁,和super对象锁并没有关系。那么这里的锁重入就很好理解了
    然后疑问又来了,是不是super实际上还是子类对象呢,接着测试一下

    public class SuperMan {
        public void soutSuperMan(){
            System.out.println("执行soutSuperMan的this对象name :"+this.getClass().getName());
        }
    }
    
    public class Man  extends SuperMan{
        public void soutMan(){
            System.out.println("执行soutMan的super对象name :" + super.getClass().getName());
            System.out.println("执行soutMan的this对象name :"+this.getClass().getName());
            super.soutSuperMan();
        }
    }
    
    public class TestSuper {
        public static void main(String[] args) {
            Man man = new Man();
            man.soutMan();
            System.out.println("------------------------");
            SuperMan superMan = new SuperMan();
            superMan.soutSuperMan();
        }
    }
    

    果然super实际上还是子类对象,那么一切就很好解释了,线程superThread 一直持有的是super的对象锁,线程childThread 持有的是child的对象锁,在通过super调用父类同步方法是,依然是只持有child的对象锁

    相关文章

      网友评论

          本文标题:可重入锁

          本文链接:https://www.haomeiwen.com/subject/efrgpftx.html