可重入锁

2018-07-17  本文已影响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的对象锁

上一篇下一篇

猜你喜欢

热点阅读