使用请求作用域时的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 楼答案
是的,这是线程安全的,只要它被声明为原型作用域bean,并且您需要创建一个由Spring调用的
init()
方法:RequestContext只能从单个线程(分配用于处理请求的线程)访问,构造函数在调用之前不会因对象创建的性质而重新进入
不过,请注意不要将其与
listOfItem
混淆,因为它在MyMapper
对象中被锁定,因此不会阻止它被getter共享(如果您的情况中没有)。我还看到它是一个抽象类,但因为listOfItem
是私有的,子类将无法访问它。如果存在引用的任何副本,则该列表的任何泄漏引用都可能被并发线程操纵(因为List
在Java中是可变的)由于这种安全性是您的目的,所以创建一个单元测试,检查字段的可见性,如果通过反射访问字段没有引发相应的异常,则该测试将失败。您可能还希望使用自己的内部标记注释对字段进行注释,以表明该字段是线程安全的。这有助于编写文档,并作为注释,帮助实现未来可能的自动化(例如,一个可以查找所有此类注释并自动运行反射测试的测试库)
看起来很干净!继续努力