今天在Github 看Java synchronized方面的知识总结时
看到一个有趣的说法“子类不能继承父类的synchronized关键字”
我心里的第一个想法是:为什么子类不能继承父类的synchronized关键字呢
于是我决定用代码实践一下
首先,我先放上测试类主类的代码,运行哪个则注释其余的代码:
package com.way.test;
public class Main {
public static void main(String[] args) {
// 注意初始化不能放在for循环中,
因为synchronized是对象锁, 锁的是对象,
如果每次for循环中都新建了一个对象, 那么这把锁就毫无意义,怎样运行都是异步的效果
Father father = new Father();
for (int i =0;i<5;i++) {
new Thread(new Runnable() {
@Override
public void run() {
father.method();
}
}).start();
}
// Son son = new Son();
//
// for (int i =0;i<5;i++) {
// new Thread(new Runnable() {
// @Override
// public void run() {
// son.method();
// }
// }).start();
// }
// SonOverride sonOverride = new SonOverride();
//
// for (int i = 0; i < 5; i++) {
// new Thread(new Runnable() {
// @Override
// public void run() {
// sonOverride.method();
// }
// }).start();
// }
}
}
// 注意初始化不能放在for循环中,
// 因为synchronized是对象锁, 锁的是对象,
// 如果每次for循环中都新建了一个对象, 那么这把锁就毫无意义,怎样运行都是异步的效果
父类的代码:
package com.way.test;
public class Father{
public synchronized void method(){
System.out.println("AA");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("BB");
}
}
中间休眠一秒是为了有足够时间观察方法是否“同步”,否则太快的话是可能看不出来。
运行结果:
可以看出AA——间隔一秒——BB是交替打印
然后,分别写两个子类,一个是直接继承上面的父类
package com.way.test;
public class Son extends Father {
}
运行结果:
可以看出跟父类是一样的,证明了是继承了父类的synchronized关键字
而另外一个则是继承并且重写了父类的方法,注意这里不要加上synchronized关键字
package com.way.test;
public class SonOverride extends Father{
@Override
public void method() {
System.out.println("AAA "+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("BBB "+Thread.currentThread().getName());
}
}
运行结果:
很明显这次运行结果是“异步的”,整个过程只间隔了一秒
倘若,我们在SonOverride中重写的方法中加上“Synchronized”关键字的话
@Override
public synchronized void method() {
那么运行结果:
可见效果跟直接继承父类类似。