How to ensure Thread safety of subclass' methods from a superclass?

喜你入骨 提交于 2019-12-05 14:25:14

After a very long research I found out that synchronization cannot be inherited if the method is overridden and without explicitly adding the keyword synchronized in the the overridden method's signature!!

And because this issue is mainly addressed to prevent other users (i.e. developers) from violating the use of your class (as they are extending it).

I came up with a way to work around it by availing of the Reflection class in Java.

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class A {
    public A(){
         assertSynch("doSomething");
    }

    // method to assert a particular method is synchronized in the subclass
    private void assertSynch(String methodName) {
        Class<? extends A> subclass = this.getClass(); // this returns the subclass
        Method[] methods = subclass.getDeclaredMethods();
        for (Method meth : methods) { // loop through the methods in subclass
            if(meth.getName().equals(methodName)) { // when it reaches your method
                String modVal = Modifier.toString(meth.getModifiers()); // get its modifier
                if(!modVal.contains("synchronized")) { // check if it contains the keyword "synchronized"
                    try { // if not -> throw an Exception with clear message about the reason and exit
                        throw new Exception(methodName + 
                             " must be synchronized to ensure class thread safety!");
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.exit(0);
                    }
                }
            }
         }
    }

    public synchronized void doSomething() {} 
}

public class B extends A{
    public B() { } // it implicitly calls the superclass constructor

    @Override
    public void doSomething() { } // it will make the program to throw the above exception
}

I would say better to make the base class doSomething method public final synchronized (final to make sure subclass can't override it) and call another protected abstract method. public synchronized final void doSmoething ensure that any call to doSomething method will be synchronized / thread safe and doSmoethingImpl abstract method will provide flexibility to give the method own definition in a subclass.

abstract class A {
    public synchronized final void doSmoething() {
        doSmoethingImpl();
    }
    protected abstract void doSmoethingImpl();


}

class B extends A {
    @Override
    protected void doSmoethingImpl() {
        // definition in class B
    }
}

Note: Above solution will not directly satisfy your point 1 but doSmoethingImpl() will give you scope to achieve the similar functionality indirectly.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!