【问题标题】:Can having a 'setter'/instance variable lead to race conditions with singleton DAOs?有一个“设置器”/实例变量会导致单例 DAO 的竞争条件吗?
【发布时间】:2012-08-22 21:00:23
【问题描述】:

假设下面的类是单例

public class myDAO {
    //determines the tableName and Id column names to based on itemType
    private String itemType;
    public void setItemType(String itemType) {...} 

    //Following methods use itemType to customize their queries
    public boolean findObj(int id){...} 
    public boolean deleteObj(int id){...}
    public boolean updateObj(Obj obj){...}
    //etc...
}

最近使用 setter 重构了代码,从而为 DAO 提供了一些状态。我看到这在 Spring 的配置文件中被配置为 singleton-scope。我有一种奇怪的感觉,这可能会导致潜在的比赛条件。对吗?

我真的不确定这是否确实如此,但如果它是真的,恕我直言,弄清楚这将是一个噩梦般的情况。我知道这可能不是最好的设计,但我只是想知道当并发线程查询不同的itemTypes 时这是否会导致竞争条件。我正在考虑将范围更改为prototype,但不确定在这种情况下是否确实需要。

【问题讨论】:

    标签: java multithreading spring singleton race-condition


    【解决方案1】:

    如果多个线程调用setItemType(...),然后调用findObj(...),并期望找到ID为的对象,那么是的,你奇怪的感觉是正确的,这个是一种潜在的竞争条件,在多线程应用程序中不起作用。

    您应该将itemType 传递给您的每个方法:

    public boolean findObj(String itemType, int id){...} 
    public boolean deleteObj(String itemType, int id){...}
    public boolean updateObj(String itemType, Obj obj){...}
    

    如果 itemType 在 Spring 构建 DAO 之后只设置一次,那么这没关系,但应该作为 Spring 配置的一部分来完成,它是单线程完成的。

    如果您必须为所有或大多数方法添加itemType 参数,那么在我看来您不再应该拥有单例。相反,您应该考虑拥有一个 DAO 工厂或其他东西,并拥有多个 DAO 实例,每个实例都有自己的项目类型。

    【讨论】:

      【解决方案2】:

      如果setItemType 方法在初始化时使用(例如通过 Spring 配置),并且如果 Spring 强制执行适当的内存屏障以确保该值在使用前在所有线程中可见,那么它可能好的-但是有点气味。这是构造函数注入更简洁的地方,因为您可以将其设为final 变量,这显然不是什么大问题。

      如果setItemType 方法用于post 初始化,那么这绝对是,绝对 一个问题。您要么需要多个实例(例如,每个类一个需要对 DAO 的引用),要么每个项目类型可能需要一个实例:声明几个单独的 bean,然后为每个需要 DAO 的类提供对“正确”一个取决于它需要哪种类型。

      【讨论】:

        猜你喜欢
        • 2021-09-03
        • 1970-01-01
        • 1970-01-01
        • 2014-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-09-23
        • 2019-03-21
        相关资源
        最近更新 更多