java - 使用请求范围时的线程安全代码

标签 java spring

我有类“RequestContext”,它的范围是request。此类具有属性 listOfItem

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

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){

}

}

最佳答案

是的,那是线程安全的只要声明为原型(prototype)范围bean,并且您需要创建一个由Spring 调用的init() 方法:

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

RequestContext 只能从单线程(分配用于处理请求的线程)访问,构造函数在调用之前创建对象的本质是不可重入的。

注意不要将它与 listOfItem 混淆,尽管它以某种方式避免重入问题,只是因为它被锁定在 MyMapper 对象中并不能阻止它被由 setter/getter 共享,如果有的话(在你的情况下没有)。我还看到它是一个抽象类,但是因为 listOfItem 是私有(private)的,子类将无法访问它。如果存在引用的任何副本(因为 List 在 Java 中是可变的),则该 List 的任何泄漏引用都可以由并发线程操作。

由于这种安全性是您的意图,因此创建一个单元测试来检查该字段的可见性,如果通过反射访问该字段没有抛出适当的异常,则测试失败。您可能还想用您自己的内部标记注释来注释该字段,以指示该字段是线程安全的。这有助于记录,并作为注释,潜在的 future 自动化(例如可以查找所有此类注释并自动运行反射测试的测试库)。

看起来很干净!继续努力。

关于java - 使用请求范围时的线程安全代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29896940/

相关文章:

java - jasperreports - excel 导出

java - 如何动态初始化 JavaFX 应用程序,而不是硬编码?

java - 加载模式映射中的旧版 Spring 框架模式

java - Spring Boot 中与 JUnit5 和 Mockito 的集成测试

java - 在本体中创建个体的代码?

java - 纹理变形,4 点

java - 如何将 bufferedreader 复制到 bufferedwriter 中以获取 Android 中的 pdf 文件

Java JPA Hibernate SqlResultSetMapping 别名

java - 使用条件 AND NOT EXISTS 将 SQL 转换为 HQL

Spring Security 3.2 CSRF 对多部分请求的支持