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

夙愿已清 提交于 2019-12-10 09:50:24

问题


I attended an interview and I was asked to design a class for the following requirement. Assume I have a class A and it can have any number of children, i.e., subclasses. The class A has a method called doSomething() which is synchronized. The requirements are :

  1. It is mandatory that all subclasses of A override the doSomething() method.
  2. All subclasses' overriden doSomething() method must be Thread safe in nature.
  3. All subclasses' must have the provision to implement their own logic for their doSomething() method implementations.
  4. Class A's constructor is upto me(the designer) to decide how to implement.

    The designer has no control on how many subclasses would be created or how they would be created,i.e., the designer can only write code for the superclass only.


I suggested to make the class abstract and also the doSomething() method abstract. This would imply classes extending my class necessarily provide their own doSomething() method.

However, I could not answer as to what exactly in my class A would ensure Thread safety for my child classes and that too just for the doSomething() method.

He gave a hint though, he said the trick is to be done in A class' constructor.

Any ideas?


回答1:


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
}



回答2:


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.



来源:https://stackoverflow.com/questions/50545604/how-to-ensure-thread-safety-of-subclass-methods-from-a-superclass

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