2017-02-16 1 views
0

まだリリースされていないプロダクションリリースのJavaアプリケーションコードは、以下の構造をとります(これは数多くの場所にあります)。クラスは、アプリケーション・コンテキストのロード中に一度だけロードされます。以前はうまくいきました。しかし、複数のスレッドを持つ回帰環境に移行すると、共有メンバー変数のために並行性の問題が発生します。Springバインドされたクラスの共有メンバー変数の置換

Class A { 

    private Set<String> codeSet = null; 

    public void method() { 

     codeSet = SomeRepo.someMethod(session.getUser()); // Heavy repo call, returns user specific data. 

     method1(); 

     method2(); 

     .... 

     methodn(); 
    } 

    private methodn() { 
     codeSet.iterator().next(); 
    } 
} 

この問題は、変数スコープをメソッドに変更し、この変数を使用する後続のすべてのプライベートメソッドに渡すことで軽減できます。ただし、これにはアプリケーションコードの変更が多く含まれています。

多くの変更を加えることなく以下の解決策があります。前もって感謝します。

+0

あなたがスレッドの問題に言及しました。競争状態または何か? –

+0

変数が同時スレッドによってアクセスされ、データが壊れる結果になる –

+0

特定のスレッドが同期または同期を完了するまで、Java ReentrantLockを使用してそのメンバをロックしようとしましたか? –

答えて

2

はい、問題は簡単に以下のリファクタリングを適用することで解決することができます。

// singleton used by multiple threads 
class A { 

    public void method() { 
     Set<String> codeSet = SomeRepo.someMethod(session.getUser()); // Heavy repo call. 
     new AProcessor(codeSet).method(); 
    } 
} 

// not a singleton, only one thread uses an instance of this class 
class AProcessor { 
    private final Set<String> codeSet; 

    AProcessor(Set<String> codeSet) { 
     this.codeSet = codeSet; 
    } 

    public void method() { 
     method1(); 
     method2(); 

     .... 

     methodn(); 
    } 

    private methodn() { 
     codeSet.iterator().next(); 
    } 
} 
+0

+1ありがとうございます。エレガントなソリューションのようですが、依然としてリファクタリングが少しあります。受け入れる前に、他の解決策がある場合はそれを待つでしょう。 –

関連する問題