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

时间:2015-04-27 13:17:22

标签: java spring

我的课程“RequestContext”,其范围为request。此类具有属性listOfItem

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

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 个答案:

答案 0 :(得分:1)

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

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

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

请注意不要将此与listOfItem混淆以防止重入问题,只是因为它被锁定在MyMapper对象中并不会阻止它被getter共享,如果一个可用(在你的情况下没有)。我也看到它是一个抽象类,但因为listOfItem是私有的,所以子类不能访问它。该列表的任何泄漏引用都可以由并发线程操纵,因为它是由引用构成的任何副本(因为List在Java中是可变的。)

由于此安全性是您的意图,因此创建一个单元测试来检查字段的可见性,如果通过反射访问字段则不会引发相应的异常。您可能还希望使用自己的内部标记注释对该字段进行注释,以指示该字段是线程安全的。这有助于文档和注释,潜在的未来自动化(例如可以查找所有此类注释并自动运行反射测试的测试基础)。

看起来很干净!保持良好的工作。