1

次のクラスがシングルトンであると仮定します

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...
}

コードは最近セッターでリファクタリングされたため、DAOに何らかの状態が与えられました。singleton-scopeこれはSpringの構成ファイルのように構成されていることがわかります。これが潜在的な競合状態につながる可能性があるという奇妙な感覚があります。あれは正しいですか?

これが実際に当てはまるかどうかは本当にわかりませんが、それを理解するのは悪夢のような状況になるでしょう。それが本当なら私見です。これが最善の設計ではない可能性があることはわかっていますが、並行スレッドが異なるをクエリしているときに、これが競合状態につながる可能性があるかどうかを知りたかっただけitemTypesです。スコープをに変更することを考えていましprototypeたが、この場合に本当に必要かどうかはわかりません。

4

2 に答える 2

2

複数のスレッドが呼び出しsetItemType(...)てから呼び出しており、idfindObj(...)item-typeを持つオブジェクトを見つけることを期待している場合、そうです、あなたの奇妙な感覚は正しいです、これは潜在的な競合状態であり、マルチスレッドアプリケーションでは機能しません。

itemType代わりに、各メソッドにを渡す必要があります。

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

DAOがSpringによって構築された後にitemTypeが一度だけ設定される場合、これは問題ありませんが、シングルスレッドで行われるSpring構成の一部として行う必要があります。

すべてまたはほとんどのメソッドに引数を追加するitemType必要がある場合は、シングルトンを使用する必要がなくなったように思われます。代わりに、DAOファクトリなどを用意し、それぞれが独自のアイテムタイプを持つ複数のDAOインスタンスを用意することを検討する必要があります。

于 2012-08-22T21:02:57.947 に答える
2

setItemTypeメソッドが初期化でのみ使用され(たとえば、Spring構成を介して)、Springが適切なメモリバリアを適用して、使用前にすべてのスレッドで値が表示されるようにする場合は、おそらく問題ありませんが、少し臭いがします。これは、コンストラクターインジェクションがより適切な場所です。これは、コンストラクターインジェクションをfinal変数にすることができるためです。これは明らかにそれほど問題ではありません。

setItemTypeメソッドが初期化後に使用される場合、それは間違いなく、間違いなく問題です。いたるところに複数のインスタンスが必要になるか(たとえば、DAOへの参照が必要なクラスごとに1つ)、場合によってはアイテムタイプごとに1つのインスタンスが必要になります。複数の個別のBeanを宣言してから、DAOが必要な各クラスに「正しい」必要なタイプに応じて1つ。

于 2012-08-22T21:03:32.637 に答える