问题导入: 如果一个线程调用了一个对象的同步方法, 那么他还能不能在调用这个对象的另外一个同步方法呢?
这里就是 synchronized 锁重入问题.
一. synchronized 锁重入
来看下面的代码:
. 这个是三个同步方法的类
- public class Synfun_UseSynfun{
- // 同步方法 1
- public synchronized void fun1(){
- System.out.println("我是一号同步方法");
- this.fun2();// 调用二号同步方法
- }
- // 同步方法 2
- public synchronized void fun2(){
- System.out.println("我是二号同步方法");
- this.fun3();// 调用三号同步方法
- }
- // 同步方法 3
- public synchronized void fun3(){
- System.out.println("我是三号同步方法");
- }
- }
线程类, 在 run 方法中调用一号同步方法:
- public class SynThreadText extends Thread {
- private Synfun_UseSynfun synfun_useSynfun;// 组合上面类
- public SynThreadText(Synfun_UseSynfun synfun_useSynfun){
- this.synfun_useSynfun=synfun_useSynfun;// 初始化上面的类
- }
- @Override
- public void run(){
- synfun_useSynfun.fun1();// 调用对象类的同步方法
- }
- public static void main(String[] args) {
- Synfun_UseSynfun synfun_useSynfun =new Synfun_UseSynfun();
- SynThreadText synThreadText=new SynThreadText(synfun_useSynfun);
- synThreadText.start();// 开启线程
- }
- }
结果如下:
总结: 可以看出一个线程调用了一个对象的同步方法, 那么他也可以调用这个对象的另外一个同步方法.
二. synchronized 锁重入支持父类继承
那么既然 synchronized 支持对象的方法重入, 那么他是否也支持子类继承父类的同步方法重入呢?
不妨这样设计代码, 在父类中有一个同步方法, 子类继承这个方法, 并且在创建一个子类的同步方法, 在这个同步方法中去调用父类的同步方法.
代码如下:
- public class SubClass extends SuperClass implements Runnable {
- @Override
- public void run(){
- this.subSynFun();
- }
- // 子类的同步方法
- public synchronized void subSynFun(){
- System.out.println("子类的同步方法");
- this.superSynFun();
- }
- public static void main(String[] args) {
- SubClass sub=new SubClass();
- Thread t =new Thread(sub);
- t.start();
- }
- }
- // 父类
- class SuperClass{
- // 父类的同步方法
- public synchronized void superSynFun(){
- System.out.println("父类的同步方法");
- }
- }
结果如下:
说明 synchronized 的方法是可以重入自己的父类同步化方法.
但是在这里要注意一点的: 当你去重写父类中的同步方法, 如果想要达到同步的效果重写方法也必须是同步化的, 反面教材代码如下:
- public class SubClass2 extends SuperClass2 implements Runnable{
- @Override
- public void run(){
- }
- // 重写后的方法不为同步的
- @Override
- public void superSynfun(){
- System.out.println("子类中重写了父类中的同步方法, 改为非同步");
- }
- }
- // 父类
- class SuperClass2{
- // 父类的同步方法
- public synchronized void superSynfun(){
- System.out.println("父类的同步方法");
- }
- }
重写的方法也必须是同步化的才能实现同步.
来源: https://www.cnblogs.com/SAM-CJM/p/9802956.html