可重入锁
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的对象锁