我参加了面试,并被要求为以下要求设计课程。 假设我有一个A类,它可以有任意数量的子节点,即子类。 A类有一个名为doSomething()的方法,它是同步的。要求是:
A类的构造函数由我决定(设计师)来决定如何实现。
设计人员无法控制将创建多少个子类或如何创建它们,即设计人员只能为超类编写代码。
我建议将类抽象化,并将doSomething()方法抽象化。这意味着扩展我的类的类必然会提供自己的doSomething()方法。
但是,我无法回答我的班级A究竟在哪些方面确保了我的子课程的线程安全,而且对于doSomething()方法也是如此。
他给了一个提示,他说这个诀窍是在A类的构造函数中完成的。
有什么想法吗?
答案 0 :(得分:1)
经过长时间的研究后,我发现,如果重写该方法并且未在重写方法的签名中明确添加关键字synchronization
,则无法继承synchronized
。
因为这个问题主要是为了防止其他用户(即开发人员)违反使用你的类(因为他们正在扩展它)。
我想出了一种利用Java中Reflection
类来解决它的方法。
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
}
答案 1 :(得分:1)
我会说更好地制作base
类doSomething
方法public final synchronized
(final
以确保子类不能覆盖它)并调用另一个protected abstract
} 方法。 public synchronized final void doSmoething
确保any call
到doSomething
方法为synchronized / thread safe
,doSmoethingImpl
抽象方法可以灵活地在子类中赋予方法自己的定义。
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
}
}
注意:上述解决方案不会直接满足您的要点1,但doSmoethingImpl()
将为您提供间接实现类似功能的范围。