有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用请求作用域时的java线程安全代码

我有一个类“RequestContext”,它的作用域是request。这个类有atribute listOfItem

现在我有了类MyMapper,在那里我需要使用这个列表。现在,当我想listOfItems时,我总是调用context.getListOfItem(),但问题是,我有很多私有方法,需要重复很多次。我在构造函数中定义这个atribute可以吗?它是线程安全的吗?:

public abstract class MyMapper{

@Autowired
protected RequestContext context;

private final List<String> listOfItem;

public MyMapper() {
    this.listOfItem = context.getListOfItem(); // is this thread safe and ok ?
}

public Object map(Object entity){

}

}

共 (1) 个答案

  1. # 1 楼答案

    是的,这是线程安全的,只要它被声明为原型作用域bean,并且您需要创建一个由Spring调用的init()方法:

    @PostConstruct
    public void init() {
        listOfItem = context.getListOfItem();
    }
    

    RequestContext只能从单个线程(分配用于处理请求的线程)访问,构造函数在调用之前不会因对象创建的性质而重新进入

    不过,请注意不要将其与listOfItem混淆,因为它在MyMapper对象中被锁定,因此不会阻止它被getter共享(如果您的情况中没有)。我还看到它是一个抽象类,但因为listOfItem是私有的,子类将无法访问它。如果存在引用的任何副本,则该列表的任何泄漏引用都可能被并发线程操纵(因为List在Java中是可变的)

    由于这种安全性是您的目的,所以创建一个单元测试,检查字段的可见性,如果通过反射访问字段没有引发相应的异常,则该测试将失败。您可能还希望使用自己的内部标记注释对字段进行注释,以表明该字段是线程安全的。这有助于编写文档,并作为注释,帮助实现未来可能的自动化(例如,一个可以查找所有此类注释并自动运行反射测试的测试库)

    看起来很干净!继续努力