首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何从超类中保证子类方法的线程安全?

如何从超类中保证子类方法的线程安全?
EN

Stack Overflow用户
提问于 2018-05-27 01:55:47
回答 2查看 596关注 0票数 5

我参加了一次面试,我被要求为以下要求设计一个课程。假设我有一个类A,它可以有任意数量的子类,即子类。类A有一个名为doSomething()的方法,它是同步的。要求是:

  1. 强制要求的所有子类重写doSomething()方法。

  1. 所有子类的重写doSomething()方法本质上必须是线程安全的

  1. 所有子类必须具有规定,才能为其doSomething()方法实现自己的逻辑

  1. A类的构造函数由我(设计者)决定如何实现。

设计器无法控制要创建多少个子类或如何创建它们,即,设计器只能为超类only.编写代码

我建议让类和doSomething()方法都抽象。这意味着扩展我的类的类必须提供它们自己的doSomething()方法。

然而,我不能回答我的A类中到底是什么可以确保我的子类的线程安全,也不能保证doSomething()方法的线程安全。

虽然他给出了一个提示,但他说诀窍是在A类的构造函数中完成的。

有什么想法吗?

EN

回答 2

Stack Overflow用户

发布于 2018-05-27 02:27:46

经过很长时间的研究,我发现如果方法被重写,并且没有在被重写的方法的签名中显式添加关键字synchronized,则无法继承synchronization!!

因为这个问题主要是为了防止其他用户(即开发人员)侵犯您的类的使用(因为他们正在扩展它)。

我想出了一种方法,通过利用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
EN

Stack Overflow用户

发布于 2018-05-27 02:37:48

我会说更好的做法是让basedoSomething方法public final synchronized (final,以确保子类不能覆盖它)并调用另一个protected abstract方法。public synchronized final void doSmoething确保any calldoSomething方法将是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
    }
}

注意:上面的解决方案不会直接满足您的第一点,但doSmoethingImpl()将为您提供间接实现类似功能的范围。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50545604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档